【问题标题】:Using variadic template as parameter for both class and method使用可变参数模板作为类和方法的参数
【发布时间】:2013-07-23 17:44:30
【问题描述】:

我的问题是关于以下代码:

    template <class...T>
    class A
    {
    public:
        template <class...S>
        static void a() { }
    };

    template <class...T>
    class B
    {
    public:
        template <class...S>
        void b()
        {
            A<T...>::a<S...>();
        }
    };

    int main(int argc, char** argv)
    {
        return 0;
    }

我有一个类A,它有一个可变参数模板并包含一个静态方法a,它有另一个可变参数模板。从其他地方(在这种情况下为B 类)我有两组不同的可变参数模板,我想将它们传递给A::a

编译器 (GCC 4.8.1) 给出以下错误消息:

    main.cpp: In static member function ‘static void B<T>::b()’:
    main.cpp:16:22: error: expected primary-expression before ‘...’ token
             A <T...>::a<S...>();
                          ^
    main.cpp:16:22: error: expected ‘;’ before ‘...’ token

另请注意,当我将方法 b() 更改为:

        void b()
        {
            A<int, char, short>::a<S...>();
        }

或其他 A 模板的规范,然后代码编译得很好。

上面的代码有什么问题?

【问题讨论】:

  • 请注意,当您在一个表达式中展开两个包时,事情会变得特别时髦:它们会同步展开
  • @sehe 这是两个单独的包扩展,而不是同时扩展两个包的单一模式(例如,f(A&lt;T&gt;::a&lt;S&gt;()...))。所以扩展是独立的。
  • @Casey 我知道,对。这就是为什么它是一个评论

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


【解决方案1】:

在此处添加模板

A<T...>::template a<S...>();

原因见评论。这在没有关键字的情况下也可以在 VC++ 上很好地编译,所以我猜它是依赖于编译器的。

【讨论】:

  • VC++ 没有在模板中实现两阶段名称查找;它有效地将每个名称视为从属名称。
  • 或者更清楚一点:MSVC 违反了标准,因为那里不需要template。它应该将A&lt;T...&gt;::a 视为一个值,然后将&lt; 视为小于,然后将S... 放在&lt; 表达式的右侧时会出现解析错误。这个想法是在实例化它们之前可以在template 中找到错误:MSVC 无法找到整个错误类别,因此它不需要template 消歧器。
猜你喜欢
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-03
  • 1970-01-01
  • 2017-10-10
  • 1970-01-01
  • 2011-08-26
相关资源
最近更新 更多