I seem to be missing something when trying to write a meta-function that calls into MPL code. The follow code fails to compile with the following error on inst2, but works fine on inst1:
error C2903: 'apply' : symbol is neither a class template nor a function template
using namespace boost::mpl;
template <typename VECTOR>
struct first_element : mpl::at_c<VECTOR, 0> {};
int main()
{
typedef vector<
vector<int, int>,
vector<int, int>,
vector<int, int>> lotso;
typedef mpl::transform<lotso,
first_element<_1>>::type inst1;
typedef first_element<
at_c<lotso,0>>::type inst2;
return 0;
}
I think you forgot a ::type
behind the call to at_c
inside the typedef for inst2
. Recall that your first_element
expects something on which at_c
can be applied. The raw at_c<lotso, 0>
, however, is not yet evaluated. Evaluating a metafunction is done by adding ::type
.
#include <boost/mpl/vector.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/placeholders.hpp>
#include <type_traits>
using namespace boost;
using namespace boost::mpl;
template <typename VECTOR>
struct first_element : mpl::at_c<VECTOR, 0> {};
int main()
{
typedef vector<
vector<int, int>,
vector<int, int>,
vector<int, int>> lotso;
typedef mpl::transform<lotso,
first_element<_1>>::type inst1;
typedef first_element<
at_c<lotso,0>::type >::type inst2;
^^^^^^ <--- you forgot a ::type here
static_assert(std::is_same<first_element<inst1>::type, inst2>::value, "bingo");
return 0;
}
Live Example. As a further check, I verified that a further dereference on inst1
gives the same type as inst2
.