1

I have a problem concerning partial class template specialization in c++. I have one class A with two templates T,U. Then i want two class specializations with exclusive methods print_me(), only visible for those two specializations. Apart from that i need fully specialized member functions add_integer/add_double. When i implement those methods in the header file, it compiles fine. But id really like my implementations to be in the source file, which is no problem for the fully specialized functions, but for the partial ones. I get following errors for the code below:

test.h:27:25: error: declaration of ‘void A<int, U>::print_me()’ outside of class is not definition [-fpermissive]
test.h:30:28: error: declaration of ‘void A<double, U>::print_me()’ outside of class is not definition [-fpermissive]

But if i leave out the declarations of print_me() in the header file i get an undefined reference error, which i understand, as my compiler cant know, which methods to instantiate when compiling.

test.h:

//Primary Template Class
template <typename T, typename U>
class A{};

//Partial Specialization 1
template <typename U>
class A<int,U>
{
public:
void add_double(double a);
void print_me();
};

//Partial Specialization 2
template <typename U>
class A<double,U>
{
public:
void add_int(int a);
void print_me();
};

//explicit specialization
template <>
void A<int,double>::add_double(double a);

//explicit specialization
template <>
void A<double,int>::add_int(int a);

//partial specialization
template <typename U>
void A<int,U>::print_me();

//partial specialization
template <typename U>
void A<double,U>::print_me();

test.cpp

#include "test.h"

template <>
void A<int,double>::add_double(double a){}

template <>
void A<double,int>::add_int(int a){}


template <typename U>
void A<int,U>::print_me(){};

template <typename U>
void A<double,U>::print_me(){};

for testing purpose main.cpp

#include "test.h"

int main()
{
A<int,double> * a_0=new A<int,double>;
A<double,int> * a_1=new A<double,int>;

a_0->add_double(1.1);
a_0->print_me();

a_1->add_int(1);
a_1->print_me();

return 0;
}

So is there any possibility to have the print_me() methods implemented in the source file? Whats the difference between fully and partially specialized member functions in this context?

Any hints will be appreciated

Peter Power
  • 121
  • 3
  • 7

1 Answers1

1

as @Angew mentioned, partial specialization is still a template, which is just a blueprint for yourprint_memethod. you need to instantiate your template function. for that you can use explicit instantiation or implicit instantiation in your test.cpp file.

Explicit Instantiation:

template
void A<double,int>::add_int(int a);

Implicit Instantiation:
just define a dummy function in test.cpp which will call the fully specialized template function print me (you don't have to use this dummy function) :

void instatiatePrintMe()
{ 
    A<int, double> a;
    a.print_me();
}

you can read here for more information: C++ - Defining class template (header/source file)

Community
  • 1
  • 1
eladm26
  • 517
  • 4
  • 23
  • Thank you for the quick answers... But i dont think i really get what youre trying to tell me. What you suggest as explicit instantiation is pretty much what i got in my example right?! And what do you mean with that dummy function? I don't want to get a new object a and call a.print_me()! What i need to do is to call the print_me() function for an object already existant like a_0 and a_1 in my main.cpp, which is not possible with the provided wrapper function. Or do i get anything wrong here? – Peter Power Jun 30 '14 at 15:30
  • I'm talking about instantiation, not specialization, those are 2 different things. in your case the functions add_int/double are specialized, the compiler treat them like any regular function, that's why you don't get any error regarding those 2 functions. the print_me function, on the other hand, is partially specialized, and the compiler treats it as a template function. when you try to call it from main.cpp, the compiler tries to generate this function with the parameters you supplied and for this it must see the template definition which is in a different translation unit, test.cpp. – eladm26 Jun 30 '14 at 16:03
  • Now i see what you mean with the function!! Its just a random call so the class will be instantiated, right?! Ok thats not very beautiful code is it?.. So would you recommend just to implement in the header? im very unexperienced its my first large project and i just dont know whats the right way to do things like that.. Thank you for taking time to explain stuff, think i get it now! – Peter Power Jun 30 '14 at 16:06
  • @PeterPower For template issues regarding header/source files, you might want to study this [faq entry](http://stackoverflow.com/q/495021/1782465). – Angew is no longer proud of SO Jun 30 '14 at 19:15
  • @PetePower in my opinion the most elegant solution is to implement the template related code in the header file. The downside of this solution is that it can cause some code bloat. – eladm26 Jun 30 '14 at 22:12