2014-02-08 75 views
2

我希望能够专注一类的构造函数的方式如下:可变参数模板的构造speciliazation

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’

如果我尝试移动类外的专业化,如下所示:

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& ...)

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

+2

不要专门化它。重载它。 – WhozCraig

回答

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

成员函数和扩展构造并不擅长,能够在不完全专业外模板。

只要写一个int不是模板的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."