3

Given the following definitions:

template <typename T>
class A {

public:

   void f();

};

template <typename T>
void
A<T>::f()
{}

template <typename T>
class B {};

How would I partially specialize A<B<T>>::f, i.e. f for some B<T>? I'm basically looking for the right magic to substitute the ??? below

template <???>
void
A<B<T>>::f()
{}
Barry
  • 286,269
  • 29
  • 621
  • 977
regnirpsj
  • 97
  • 6

4 Answers4

3

You can have an explicit specialization, from [temp.expl.spec]:

An explicit specialization of any of the following:
— ...
— member function of a class template
— ...
can be declared by a declaration introduced by template<>

That is:

template <>
void A<B<int>>::f() {
    std::cout << "B\n";
}

But you cannot have a partial specialization of a member function of a class template. You would have to partially specialize the entire class:

template <typename T>
class A<B<T>> {
public:
    void f() {
        std::cout << "B\n";
    }

    // ... all other members you want in A<B<T>> ...
};
Barry
  • 286,269
  • 29
  • 621
  • 977
  • do you know where in the standard this is made explicit, i.e. no partial specialization of a member function of a class template allowed? – regnirpsj May 08 '15 at 19:12
  • @regnirpsj It's sort of implied by "The template parameter list of a member of a class template partial specialization shall match the template parameter list of the class template partial specialization. The template argument list of a member of a class template partial specialization shall match the template argument list of the class template partial specialization." – Barry May 08 '15 at 19:12
  • Thanks. I never really liked the lawyerese in standard but after some parsing it makes sense. – regnirpsj May 08 '15 at 19:16
  • @regnirpsj you may also check **14.8 Function template specializations [temp.fct.spec]** – vsoftco May 08 '15 at 19:18
1

You cannot partially specialize a member function (nor in fact any function). You need to partially specialize the whole class:

template<typename T>
class A<B<T>>
{
    // implement member functions for this specialization here
};
vsoftco
  • 55,410
  • 12
  • 139
  • 252
0

If you must have:

template <typename T>
void A<B<typename T>>::f() {}

then your only choice is to partially specialize A.

template <typename T> class A<B<T>>
{
   public:
      void f();
};
R Sahu
  • 204,454
  • 14
  • 159
  • 270
-2

C++11 has Alias Templates, allowing you do do something like:

template<T>
using AB = A<B<T>>;

Then you can refer to AB<T> instead of A<B<T>>.

Unfortunately, you can't use that for specialization..

So seems to me the answer to your question is: You can't do that, but it's a shame.

Community
  • 1
  • 1
zmbq
  • 38,013
  • 14
  • 101
  • 171
  • What do alias templates have to do with the OP's problem? – dyp May 08 '15 at 18:59
  • They're the first half of the solution. – zmbq May 08 '15 at 19:00
  • 2
    I have no idea how they're the first half of a solution, given that you may not partially specialize member functions. If it were allowed, it'd probably be just `template void A>::f() {}` – dyp May 08 '15 at 19:02