“使用类模板需要模板参数列表”错误,即使使用模板模板,也需要模板类

时间:2014-06-12 06:47:44

标签: c++ templates metaprogramming

上下文/最终愿望(虽然与问题几乎无关)

为许多元素类型的容器做很多大小的基准测试。

至少我希望有一个类型列表的模板组合器来创建foreach(foreach)方案。 (从两个4-elems列表中获取16个元素的列表。)

我没有boost mpl,也没有C ++ 11。:'(

我首先尝试创建一个对列表,其中list1的第一个元素在一个新列表中重复,其中第二个元素将是list2元素的副本。 这将是第一步。 (最终目标是获得list1大小的列表,由所有组合的对列表组成。)

无论如何我遇到了一个实际问题,我有一个Transform元函数,只接受带有1个模板参数的谓词作为变换函数。

但我希望创建一个从2参数元函数到一个带有1个参数的闭包,但在typedefing期间存储了第一个。

我做到了:

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;
};

真正的问题

编译器(visual studio 2012),正在给我:

  

1&gt; .. \ BenchmarkApp.cpp(648):错误C2955:'Meta :: Unarify :: U'   :使用类模板需要模板参数列表

这发生在代码提取的最后五行。 在这一行:

struct UnaryPairMaker : Unarify< MakePair, ToPlaceLeftT >::U

我觉得这很奇怪,因为我将2-args模板类(MakePair)放入Unarify的template-template参数中,通常应该接受它。

应该接受它,因为Unarify的第一个模板参数应该是模板类。并且编译器抱怨它....是模板类....

这到底是怎么回事?

编辑:解决方案

这些男/女为你未来的读者,如WhozCraig和Marco A.都提到过,问题是::U而不是MakePair。疯狂快速扫描能力的家伙们,尊重。

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;
};

我们走了。这是可能的人!是的,可以将二元元函数中的类型关闭为一元元函数,该元函数可以通过将一元元函数作为函子的元算法。呵呵。 C ++只是吓坏了。

1 个答案:

答案 0 :(得分:2)

U需要一个参数(参见其声明)

template < typename T2 >
    struct U
    {

你没有在行中传递任何内容

template < typename T >
    struct UnaryPairMaker : Unarify< MakePair, ToPlaceLeftT >::U

可能的解决方案:

template < typename T >
    struct UnaryPairMaker : Unarify< MakePair, ToPlaceLeftT >::template U<T>
    {
    };

另请注意模板关键字:如果您的编译器遵循标准

,那么这不是可选的
  

当成员模板专业化的名称出现之后。要么    - &GT;在postfix-expression中,或在qualified-id中的nested-name-specifier之后,以及postfix-expression或qualified-id   取决于模板参数(14.6.2),即成员模板名称   必须以关键字模板为前缀。否则名称是   假设命名为非模板。