#c #function #templates #member #template-specialization
Вопрос:
приведенный ниже код не компилируется
#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);
}
в качестве специализированного метода «записи» A и B создают экземпляр шаблона «добавления» A или B. При компиляции жалобы компилятора
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;};
На данный момент я не вижу, как можно упорядочить функции, чтобы избежать этой проблемы, за исключением того, что я отказываюсь от специализации.
Любые предложения высоко ценятся.
Ответ №1:
Вы можете объявлять специализации методов шаблона после каждого объявления класса:
#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);
}
В коде есть комментарий о том, что метод B<int>::add(A<int> x)
вызывается, A<int>::write(B<int> x)
но не был объявлен или определен ранее.
Комментарии:
1. это сделало свое дело. потрясающе.