1
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);
}

Compiler gave:

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’

If I move the BarSelector outside class A, it works.

What's the correct syntax to keep them inside class A?

Thanks!

Hei
  • 1,844
  • 3
  • 21
  • 35

1 Answers1

2

What's the correct syntax to keep them inside class A?

No, explicit specialization can't be put in a class scope, it must be put in namespace scope.

From the standard, $14.7.3/2 Explicit specialization [temp.expl.spec]

An explicit specialization shall be declared in a namespace enclosing the specialized template.

So you have to move it outside the class, such as:

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

Note that it's impossible to specialize a member without explicitly specializing the containing class. That might be a side note about why can't explicit specialize a member template in class scope (which let you specialize a member template without explicitly specializing the outside class template).

songyuanyao
  • 169,198
  • 16
  • 310
  • 405