Reputation: 6775
do a benchmark for lots of sizes for lots of containers for lots of element types.
at least I would like to have a template combiner of type-lists to create a foreach(foreach) scheme. (obtain a 16-elements list from two 4-elems lists.)
I do not have boost mpl, nor C++11. :'(
I am trying at first to create a list of pairs with the first element of list1 being repeated all over a new list, where second elements would be copies of elements of list2. that would be the first step. (final goal is to obtain a list of the size of list1, made of list of pairs with all the combinations.)
anyway I bump into a little practical issue, where I have a Transform meta function that accepts only a Predicate with 1 template argument as the transformer function.
But I wish to create a closure from a 2 argument metafunction to one that takes 1 argument but has stored the first during typedefing.
I did that:
template < template <class> class Principal, typename TypeListN_T >
struct Transform
{
typedef typename detail::TransformAux<Principal, TypeListN_T, EmptyT, Length<TypeListN_T>::value - 1 >::Value_t Value_t;
};
template < typename T1, typename T2 >
struct Pair
{
typedef T1 First_t;
typedef T2 Second_t;
};
template < typename T1, typename T2 >
struct MakePair
{
typedef Pair< T1, T2 > Value_t;
};
template < template < class, class > class Binary, typename T >
struct Unarify
{
template < typename T2 >
struct U
{
typedef Binary< T, T2 > value_t;
};
};
// create a list of " Pair<Tfirst, List::At< i > > " for each i in List.
template < typename TFirst, typename List >
struct EmplaceListInSecond
{
typedef typename List::Head_t ToPlaceRightT;
typedef TFirst ToPlaceLeftT;
template < typename T >
struct UnaryPairMaker : Unarify< MakePair, ToPlaceLeftT >::U
{
};
typedef typename Transform< UnaryPairMaker, List >::Value_t Value_t;
};
the compiler (visual studio 2012), is giving me:
1>..\BenchmarkApp.cpp(648): error C2955: 'Meta::Unarify::U' : use of class template requires template argument list
this happens on the last-fifth line in the code extract. on this line:
struct UnaryPairMaker : Unarify< MakePair, ToPlaceLeftT >::U
Which I find super strange, because I am placing a 2-args template class (MakePair) into the template-template parameter of Unarify, where normally it should be accepted.
It should be accepted because the first template argument of Unarify is supposed to be a template class. And the compiler complains that it .... is a template class....
what the hell is going on here ?
Here guys/girls for you future readers, like WhozCraig and Marco A. both mentioned, the problem was ::U
and not MakePair
. Crazy quick code scanning ability guys, respect.
template < template < class, class > class Binary, typename T >
struct Unarify
{
template < typename T2 >
struct U
{
// little fix here compared to previous version ::Value_t wasnt called.
typedef typename Binary< T, T2 >::Value_t Value_t;
};
};
// create a list of " Pair<Tfirst, List::At< i > > " for each i in List.
template < typename TFirst, typename List >
struct EmplaceListInSecond
{
typedef typename List::Head_t ToPlaceRightT;
typedef TFirst ToPlaceLeftT;
// big fix here, ::U is a template class that needed an argument (INDEED !!)
// I was mistakenly taking the message for a MakePair problem, maybe would
// have it been cland I would have seen the column number. well whatever...
// T is the actual PLACEHOLDER that will accept the values passed during
// visitation by the Transform function, and it is the type we want for U's T2 !
template < typename T >
struct UnaryPairMaker : Unarify< MakePair, ToPlaceLeftT >::template U<T>
{
};
typedef typename Transform< UnaryPairMaker, List >::Value_t Value_t;
};
There we go. it IS POSSIBLE MAN ! Yes, it is possible to close a type from a binary metafunction into an unary metafunction passable to a meta-algorithm that takes a unary metafunction as a functor. hehe. C++ just freaking rocks.
Upvotes: 1
Views: 2510
Reputation: 43662
U requires an argument (see its declaration)
template < typename T2 >
struct U
{
you're not passing any in the line
template < typename T >
struct UnaryPairMaker : Unarify< MakePair, ToPlaceLeftT >::U
A possible solution:
template < typename T >
struct UnaryPairMaker : Unarify< MakePair, ToPlaceLeftT >::template U<T>
{
};
Also note the template keyword: that is not optional if your compiler follows the standard
When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.
Upvotes: 2