Reputation: 75
I have m ints and n floats and I want to iterate over them in one loop. In order to do so, I can think of two possible ways but I don't know if they are actually feasible:
Ideally I want to store the m+n numbers in one array (e.g. in one std::vector), is there a way (a container, or by means of polymorphism) that I could do this?
If I must store the ints and floats in two arrays, is there (or how to write) an iterator that can iterate the two arrays in on loop?
Any idea is welcome!
Upvotes: 1
Views: 1186
Reputation: 217235
You may factorize your code differently, for example:
struct MyData {
template <typename FUNC>
void run(FUNC func) {
for (auto& i : ints) {
func(i);
}
for (auto& f : floats) {
func(f);
}
}
std::vector<int> ints;
std::vector<floats> floats;
};
And then, usage is similar to
MyData myData = /**/;
myData.run([](auto e){ std::cout << e << " "; });
Upvotes: 1
Reputation: 3877
It seems a template function might be a good solution:
-O3
double
, int64_t
, int32_t
etc.)It would look like this:
template<typename T>
void processData(std::vector<T> data) {
for (auto& d : data) {
// do some processing
}
}
you would call it with:
processData(std::vector<float>{1.2, 2.5, 3.5, 4.5});
processData(std::vector<int>{1, 2, 3, 4});
see a working example here
Upvotes: 2
Reputation: 930
There are several options, with all their different advantages and disadvantages:
Use two std::vector, one for int the other for float, and iterate them in separate loops. If the loop body is non-trivial, put it into a templated function, so you don't have to duplicate the code.
Use an std::vector of boost::any, which can store both floats and ints. When acquiring the value, you have to "cast" it into the right type. Again you might want to put any logic into a templated function to avoid code duplication. Since the boost::any cast to the actual type involves type checking, this solution has not optimal performance. On the other hand it comes close to the behavior of runtime-typed languages like Python.
Especially if you have more then just two types: Use a boost::fusion::map of the type (float and int) to the vector of the type. You can iterate the map with boost::fusion::foreach, which will call a templated function and pass the vectors to it. This way you get essentially the first solution, but this time it scales more easily for many data types.
Since C++ is statically typed, there is no way to have a single container containing both floats and ints without boost::any. Exception: if the number of entries is fixed at compile time, a boost::mpl::vector could help you.
Edit: If you want code examples, give use more information which way you want to go...
Upvotes: 2
Reputation: 8573
Either create a struct and use that as your array:
struct my_compund_type {
int integer;
float very_narrow_and_possibly_I_meant_double_float;
};
std::vector<my_compund_type> array;
Your other option is to do a for loop that only iterates over the indexes, and access both arrays as necessary.
Upvotes: 0