关于c ++:模板类中的Variadic模板构造函数特化

Variadic template constructor speciliazation in template class

我希望能够通过以下方式专门化类的ctor:

1
2
3
4
5
6
7
8
9
10
11
12
13
template<typename T>
class Foo {
public:
  template<typename... Ts>
  Foo(Ts... & args) {
    // ...
  }

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

我得到以下错误:

error: explicit specialization in non-namespace scope ‘class Foo’

如果我尝试将专业化移出类,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<typename T>
class Foo {
public:
  template<typename... Ts>
  Foo(Ts &... args) {
    // ...
  }
};

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

我得到以下错误:

error: prototype for ‘Foo::Foo(int)’ does not match any in class
‘Foo’

error: candidate is: template template
Foo::Foo(Ts& ...)

如何正确执行此操作?


您可以只重载构造函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
template<typename T>
class Foo {
public:
  template<typename... Ts>
  Foo(Ts&... args) {
    // ...
  }

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

重载解决方案更倾向于非模板重载,因此执行Foo f(1234);将选择Foo::Foo(int);

实况示例(我已经将variadic修改为const,以便它为示例接受临时变量)。

注意,类型修饰符在变量函数中的位置是错误的。它应该是同一类型的,在...的左侧:

1
Foo(Ts&...  args)


如果不完全专门化外部模板,则无法专门化成员函数和by-extension构造函数。

只需使用int而不是template编写ctor就可以了。

14.7.3p18:"In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope,
the member template and some of its enclosing class templates may
remain unspecialized, except that the declaration shall not explicitly
specialize a class member template if its enclosing class templates
are not explicitly specialized as well."