【问题标题】:Why does this variadic template specialization definition not compile?为什么这个可变参数模板特化定义不能编译?
【发布时间】:2013-06-26 23:46:47
【问题描述】:

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

prog.cpp:在函数“int main()”中:prog.cpp:27:63:错误: 'Erase >::Result' 没有被删除 声明

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

标准中是否引用了关于无法在两个参数包中间推断元素的内容,就像我尝试对第一个代码块做的那样?

【问题讨论】:

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


    【解决方案1】:

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

    ——一个不在参数声明子句末尾出现的函数参数包。

    所以在:

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

    Head不能推导出来;它不会出现在参数列表的末尾。

    相比之下,在:

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

    ToAppendList 都出现在各自参数列表的末尾,因此可以推导出来。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多