views:

276

answers:

1

I got trouble in creating special instance of member template function of non-template class. I have, for example, class A with template member function F:

class A
   {public:
      template <class T> int F (T arg) const;
      ....
   }

and want to have a special instance of this template function F for type B:

class B;
...
template <> void A::F (B arg) const //GOOD!

and it works perfectly, until appears that B is a template itself!

This code

template <class T> class B ...
...
template <> void A::F (B<T> arg) const //error, T undeclared

as well as

template <class T> class B ...
...
template <class T> template <> void A::F (B<T> arg) const //error, too many templates

gives compiling error.

The second trouble is, how to declare this special instance (or template instance at whole) to be friend function of class B? (Is does not work even if B is not a template).

class B
   {friend template <> void A::F (B arg) const // error
     // as well as
    template <> friend void A::F (B arg) const // error
   }

Is there a way to write code in a way I'm going to at all or it is not possible?

+1  A: 

You're attempting to create a partial specialization for a function template, which is illegal. What you can do is simply create an overload.

To create a friend, you merely have to use the correct syntax.

The following compiles without errors.

template <typename T>
struct B {};

struct A
{
    template <typename T>
    void F(T arg) const;

    template <typename T>
    void F(B<T> arg) const;

    template <typename T>
    friend void G(B<T> arg);

    template <typename T>
    friend struct B;
};
avakar
Sorry, I'm afraid I haven't catch the syntax, could you show in the example of class A's member Fclass A {template <class T> int F (T arg) const; }to be friend of class B, please!
Nick
Oh I see, you can't grant friendship to a member function. You can grant it to the class though: `friend class A;`. I've added an example to the answer.
avakar
Thanks a lot, I supposed so, maybe even I have heard about it before, it is not a problem to declare friend class A, so I do not care. But it is very sad that I can't create partial specialization.
Nick
Why would you want to?
avakar
Cos B-like classes are group of special data containers (like tables which are actually might be kept on disk because they are to big to fit into memory and so on), A class is a display routine for all types (like proper screen output). In most case A know what to do with B, but in some may not, that's why I wanted to add specialization. It was OK until B wasn't template.Although later I saw that I would not set into big trouble because A.F(B) is not actually needed since it is even better if B will do everything itself, I was still theoretical interested in the solution of the problem.
Nick
Right, it's better if `B` handles that. If you really wanted users to influence the behavior of `A`, you can always create a free function `void foo(A, T)` that can be easily overloaded. You can even have the member `A::G` and have it call `foo`.
avakar
Yeah, overloaded free function was my first idea, but I found that if template realization would be possible it will be more elegant... So, I expected that it is possible just because in some sense template is a way of creation of overloading. Thanks a lot again, I'll choice the solution where B handles it's screen representation.
Nick