专业化模板内部的模板化结构

时间:2016-02-10 14:46:17

标签: c++ c++11

template <class T1, class T2>
class A {

template <typename T>
struct BarSelector {
    void bar(T*) {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

template <> struct BarSelector<D> {
    void bar(D*) {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

public:
    void foo(T2* pT2) {
        // do something
        BarSelector<T2> selector;
        selector.bar(pT2);
    }
};

int main() {
    C c;
    A<B, C> a1;
    a1.foo(&c);

    D* pD;
    A<B, D> a2;
    a2.foo(pD);
}

编译器给出了:

toverloading.cpp:20:11: error: explicit specialization in non-namespace scope ‘class A<T1, T2>’
 template <> struct BarSelector<D> {
           ^
toverloading.cpp:20:20: error: template parameters not used in partial specialization:
 template <> struct BarSelector<D> {
                    ^
toverloading.cpp:20:20: error:         ‘T1’
toverloading.cpp:20:20: error:         ‘T2’

如果我将BarSelector移到A类之外,它就可以了。

将它们保留在A类中的正确语法是什么?

谢谢!

1 个答案:

答案 0 :(得分:2)

  

将它们保留在A类中的正确语法是什么?

不,显式专业化不能放在类范围内,必须放在命名空间范围内。

从标准,$ 14.7.3 / 2显式专业化[temp.expl.spec]

  

应在包含专用模板的命名空间中声明显式特化。

所以你必须把它移到课外,例如:

template<> 
template<> 
class A<B, D>::BarSelector<D> {
    void bar(double*) {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

请注意,如果没有明确地专门化包含类,则无法专门化成员。这可能是一个侧面说明,为什么不能在类范围内显式专门化成员模板(这使您可以专门化成员模板而无需专门化外部类模板)。