the code below doesn't compile
#include <iostream>
using namespace std;
template<class T> class A;
template<class T> class B;
//@@@@@@@@@@@@@y
template<class T>
class B{
int x=1;
public:
void write(A<T> x);
void add(A<T> x);
};
template<class T>
class A{
int x=1;
public:
void write(B<T> x);
void add(B<T> x);
};
template<class T> void A<T>::write(B<T> x){cout<<"write generic A"<<endl;x.add(*this);};
template<class T> void A<T>::add(B<T> x){cout<<"add generic A"<<endl;};
template<> void A<int>::write(B<int> x){cout<<"write special A"<<endl;x.add(*this);};
template<> void A<int>::add(B<int> x){cout<<"add special A int"<<endl;};
template<class T> void B<T>::write(A<T> x){cout<<"write generic B"<<endl;x.add(*this);};
template<class T> void B<T>::add(A<T> x){cout<<"add generic B"<<endl;};
template<> void B<int>::write(A<int> x){cout<<"write special B"<<endl;x.add(*this);};
template<> void B<int>::add(A<int> x){cout<<"add special B"<<endl;};
int main(){
B<int> b;
A<int> a;
b.write(a);
}
as the specialized "write" method of A and B instantiate a template of "add" of A or B. When compiling the compiler complaints
error: specialization of ‘void B<T>::add(A<T>) [with T = int]’ after instantiation
32 | template<> void B<int>::add(A<int> x){cout<<"add special B"<<endl;};
I cannot see at the moment how the functions can be ordered to avoid this problem, except I drop the specialization.
Any suggestions highly appreciated.
CodePudding user response:
You can declare specializations of template methods after each class declaration:
#include <iostream>
using namespace std;
template<class T> class A;
template<class T> class B;
//@@@@@@@@@@@@@y
template<class T>
class B{
int x=1;
public:
void write(A<T> x);
void add(A<T> x);
};
// declare specializations:
template<> void B<int>::write(A<int> x);
template<> void B<int>::add(A<int> x);
template<class T>
class A{
int x=1;
public:
void write(B<T> x);
void add(B<T> x);
};
// declare specializations:
template<> void A<int>::write(B<int> x);
template<> void A<int>::add(B<int> x);
template<class T> void A<T>::write(B<T> x){cout<<"write generic A"<<endl;x.add(*this);};
template<class T> void A<T>::add(B<T> x){cout<<"add generic A"<<endl;};
template<> void A<int>::write(B<int> x){cout<<"write special A"<<endl;x.add(*this);}; // method "B<int>::add(A<int> x)" is called but was not declared or defined before
template<> void A<int>::add(B<int> x){cout<<"add special A int"<<endl;};
template<class T> void B<T>::write(A<T> x){cout<<"write generic B"<<endl;x.add(*this);};
template<class T> void B<T>::add(A<T> x){cout<<"add generic B"<<endl;};
template<> void B<int>::write(A<int> x){cout<<"write special B"<<endl;x.add(*this);};
template<> void B<int>::add(A<int> x){cout<<"add special B"<<endl;};
int main(){
B<int> b;
A<int> a;
b.write(a);
}
There is a comment in the code about method B<int>::add(A<int> x)
is called in A<int>::write(B<int> x)
but was not declared or defined before.