为什么这个可变参数模板特化定义不能编译?

时间:2013-06-26 23:46:47

标签: c++ c++11 variadic-templates typelist

使用gcc 4.7.3,我收到以下错误

  

prog.cpp:在函数'int main()'中:prog.cpp:27:63:错误:   '删除> ::结果'还没有   声明

this code

template <typename... List>
struct TypeList
{
    enum
    {
        Length = sizeof...(List)
    };
};

template <typename ToErase, typename... List>
struct Erase;

template <typename ToErase>
struct Erase<ToErase, TypeList<>>
{
    typedef TypeList<> Result;
};

template <typename ToErase, typename... Head, typename... Tail>
struct Erase<ToErase, TypeList<Head..., ToErase, Tail...>>
{
    typedef TypeList<Head..., Tail...> Result;
};

int main()
{
    static_assert(Erase<double, TypeList<int, double, char>>::Result::Length == 2, 
    "Did not erase double from TypeList<int, double, char>");

    return 0;
}

我不明白为什么代码无法编译给定我收到的错误消息,因为类似的情况确实编译干净:

template <typename ToAppend, typename... List>
struct Append;

template <typename ToAppend, typename... List>
struct Append<ToAppend, TypeList<List...>>
{
    typedef TypeList<List..., ToAppend> Result;
}

template <typename... ToAppend, typename... List>
struct Append<TypeList<ToAppend...>, TypeList<List...>>
{
    typedef TypeList<List..., ToAppend...> Result;
}

标准中是否有一个关于无法在两个参数包中间推断出元素的引用,比如我正在尝试使用第一个代码块?

1 个答案:

答案 0 :(得分:3)

§14.8.2.5(从类型中推导出模板参数)第5段列出了无法推导出模板参数的上下文。相关的是列表中的最后一个:

  

- 一个函数参数包,它不会出现在参数声明子句的末尾。

所以:

struct Erase<ToErase, TypeList<Head..., ToErase, Tail...>>

Head无法推断;它不会出现在参数列表的末尾。

相反,在:

struct Append<TypeList<ToAppend...>, TypeList<List...>>

ToAppendList都显示在各自参数列表的末尾,因此可以推断出它们。