How to declare special instance of template function for some types

I got a question of possibility of creationg special instance of member template function of non-template class. I have, for example, class A with template member function F:

1
2
3
4
5
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:

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


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

This code

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


as well as

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


gives compiling error.
Last edited on
http://www.cplusplus.com/doc/tutorial/templates/
Scroll down to the part on template specialization.
tummychow, oh, I'm afraid I found nothing there, because it is all about specialization to concrete types and nothing about specialization in the case when specialization type is template itself.
Wait... you are trying to specialize a template for a template of itself? To be honest I don't know if that is even possible. (although it is with class type)
Last edited on
Oh, I'm afraid that it is not possible too, I just hoped that there is a solution. In fact at the moment I have more theoretical interest since I can easily bypass the problem, but who knows what I'll need in future. So I want to clean the possibility or impossibility of such usage of templates.
Actually, nvm. That section I gave you should still work. If you created a template of templates, you would still eventually need a concrete or class type to boil down to it. You can't just keep nesting template within template forever because it needs to be a template of something.
vector < vector <> >; // Vector of vectors of what?
So you could theoretically create such a specialization. You'd just have some major work to do. Whether or not it is actually syntactically possible is beyond me however. Try it and see!
Last edited on
template <class T> void A::F(B<T> arg) const

That doesn't work?
tummychow, theoretically I could simply add overloaded free function

1
2
3
template <class T> int _F (T arg) const;
...
template <class T> int _F (B<T> arg) const;


to be called from A::F. I just hoped that since template is declaration of overloading (in some cases) I could find more elegant solution.

Disch
Obviously not, because it occurs that such A::F does not match prototype of A::F. It would work only if I'll add it:

1
2
3
4
5
6
class A
   {public:
      template <class T> int F (T arg) const;
      template <class T> int F (B<T> arg) const;
      ...
   }


but

 
template <> void A::F (C arg) const


works without adding
1
2
3
4
5
6
class A
   {public:
      template <class T> int F (T arg) const;
//      int F (C arg) const; // -- not needed!
      ...
   }


So this is how the question appeared.
Last edited on
Obviously not

And if it was not obvious? You're the one asking the question, and if the question was being asked evidently something was unclear.
Anyway, I don't understand what that means:
template is declaration of overloading

Keep in mind that, each time a template (whether class or function) is used with a different type, a new version is created and instantiated, so there is no actual overloading happening.
1
2
vector<int> ivec;
vector<double> dvec; // there is no overload, dvec is literally a new type 

And as far as I can see, you should be able to create a template from another template. So I'm not sure what is going wrong. What are the exact compilation errors you are getting?
Lots of questions there.

1. You cannot change the return type of the function in the specialization by the way.

2. If B is a template class - You do not need to specialize the function just for that.
In other words:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <iomanip>
#include <algorithm>

using namespace std;


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



//B is a template class
template <class W>
class B
{


};

//Generic function will do for any type which includes any type of B
template <class T> 
int A::F (T arg) const
{ 
  return 0;
}


int main()
{
 
    A a;
    B<int> b;
    
    a.F(3); //OK - T=int
    
    a.F(b); //OK - T = B<int>
    

return 0;
    
}

Last edited on
tummychow, theoretically I could simply add overloaded free function


This is basically what I was getting at. If you can't specialize the template, the next best thing is to overload the function.

Of course that only works with function templates and not class templates.

Anyway as for your actual question, I don't have an answer for you. Sorry.
I'm with Disch, there is no further light I can shed on the matter. Just overload the function if you can't get the behavior you want by more advanced means.
Topic archived. No new replies allowed.