模板类中的变量模板构造函数特化

时间:2014-02-08 09:23:17

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

我希望能够通过以下方式专门化课程:

template<typename T>
class Foo {
public:
  template<typename... Ts>
  Foo(Ts... & args) {
    // ...
  }

  template<>
  Foo(int i) {
    // ...
  }
};

我收到以下错误:

  

错误:非命名空间范围'class Foo'

中的显式特化

如果我尝试将专业化移到课外,如下所示:

template<typename T>
class Foo {
public:
  template<typename... Ts>
  Foo(Ts &... args) {
    // ...
  }
};

template<typename T>
template<int>
Foo<T>::Foo(int i) {
    // ...
}

我收到以下错误:

  

错误:'Foo :: Foo(int)'的原型与类中的任何一个都不匹配   “富”

     

错误:候选者是:模板模板   Foo :: Foo(Ts&amp; ...)

我该如何正确地做到这一点?

2 个答案:

答案 0 :(得分:2)

您可以改为重载构造函数:

template<typename T>
class Foo {
public:
  template<typename... Ts>
  Foo(Ts&... args) {
    // ...
  }

  // template<>  <- REMOVE THIS
  Foo(int i) {
    // ...
  }
};

重载解析更喜欢非模板重载,因此Foo<MyType> f(1234);会选择Foo<MyType>::Foo(int);

LIVE EXAMPLE(为了示例,我已将变量值修改为const以接受临时值。)

请注意,可变参数函数中类型修饰符的位置是错误的。它应该是...左侧的类型:

Foo(Ts&...  args)

答案 1 :(得分:1)

如果没有完全专门化外部模板,

成员函数和扩展构造函数是不可专门的。

只需用int而不是模板编写ctor就可以了。

  

14.7.3p18:“在类模板成员或名称空间作用域中出现的成员模板的显式特化声明中,   成员模板及其一些封闭的类模板可以   除非声明不明确,否则仍然没有专业化   如果它包含类模板,则专门化一个类成员模板   也没有明确的专业。“