Generally, I would use boost::mpl::for_each<>()
to traverse a boost::mpl::vector
, but this requires a functor with a template function declared like the following:
template<typename T> void operator()(T&){T::staticCall();}
My problem with this is that I don't want the object T to be instantiated by for_each<>
. I don't need the T parameter in the operator()
at all. Is there a way to accomplish this, or an alternative to for_each<>
that doesn't pass an object of type T to the template function?
Optimally, I would like the operator() definition to look like this:
template<typename T> void operator()(){T::staticCall();}
And of course, I don't want T to be instantiated at all prior to the call. Any other tips/suggestions are also welcome.
The iterator is not the only way to iterate through any STL container. There exists a better and efficient way to iterate through vector without using iterators. It can be iterated using the values stored in any container. Below is the syntax for the same for vectors:
The most classic C++ way to iterate over elements is using iterators. Remember that using vector::begin () and vector::end () allow accessing at pointers to the start and end of a vector respectively. Moreover, you can use vector::rbegin () and vector:rend () to get the reverse iterator pointing the last and the first element respectively.
Updating values in vector: For updating values in a vector without using iterators traverse the values stored in vector using reference and updated the value. Below is the syntax for the same: Explanation: Here itr is an address to the value stored in vector which is used to traverse vectors.
Now, with a vector filled with random number, the subsequent step is checked which elements are stored on it. Using an index is a most used/classic way to iterate over the vector in C++, which is used in normal loops. With this approach it is possible to know the index position of the elements.
Just encountered the same situation and provided different solution to the problem which I would like to share. It's not as that obvious, but it uses an existing algorithm. The idea is to use pointers instead.
typedef boost::mpl::vector<type1*, type2*> container;
struct functor
{
template<typename T> void operator()(T*)
{
std::cout << "created " << typeid(T).name() << std::endl;
}
};
int main()
{
boost::mpl::for_each<container>(functor());
}
so here we get a null pointers, but we don't care as we are not going to use them.
As I stated before that is not obvious in the code and would probably require some additional comments, but it still solves the question without writing any additional code.
added
I think Diego Sevilla suggested something similar.
Interesting question! As far as I can tell, Boost.MPL does not seem to provide such an algorithm. However, writing your own should not be too difficult using iterators.
Here is a possible solution:
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/vector.hpp>
using namespace boost::mpl;
namespace detail {
template < typename Begin, typename End, typename F >
struct static_for_each
{
static void call( )
{
typedef typename Begin::type currentType;
F::template call< currentType >();
static_for_each< typename next< Begin >::type, End, F >::call();
}
};
template < typename End, typename F >
struct static_for_each< End, End, F >
{
static void call( )
{
}
};
} // namespace detail
template < typename Sequence, typename F >
void static_for_each( )
{
typedef typename begin< Sequence >::type begin;
typedef typename end< Sequence >::type end;
detail::static_for_each< begin, end, F >::call();
}
[The naming may not be very well chosen, but well...]
Here is how you would use this algorithm:
struct Foo
{
static void staticMemberFunction( )
{
std::cout << "Foo";
}
};
struct Bar
{
static void staticMemberFunction( )
{
std::cout << "Bar";
}
};
struct CallStaticMemberFunction
{
template < typename T >
static void call()
{
T::staticMemberFunction();
}
};
int main()
{
typedef vector< Foo, Bar > sequence;
static_for_each< sequence, CallStaticMemberFunction >(); // prints "FooBar"
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With