次のコードを検討してください。
template<typename T>
class Base
{
template<typename U>
friend void f(void *ptr) {
static_cast<Base<U>*>(ptr)->run();
}
protected:
virtual void run() = 0;
};
class A : public Base<A>
{
protected:
virtual void run() {}
};
/*
class B : public Base<B>
{
protected:
virtual void run() {}
};
*/
現在は正常にコンパイルされています ( ideone )。しかし、 の定義のコメントを外すB
と、次のエラー ( ideone )が発生します。
prog.cpp: In instantiation of ‘Base<B>’:
prog.cpp:20: instantiated from here
prog.cpp:6: error: redefinition of ‘template<class U> void f(void*)’
prog.cpp:6: error: ‘template<class U> void f(void*)’ previously defined here
このエラーが発生する理由を知っています(まあ、知っていると思います)。
だから私の質問は:
フレンド関数テンプレートのクラス内定義の場合の再定義エラーを回避するには?
クラス内でプライマリ テンプレート(特殊化ではない)の定義を提供する限り、このエラーが発生します。この方法でプライマリ テンプレートを定義することには、別の問題もあります。クラス テンプレートのすべてのインスタンス化のf
関数テンプレートfriend
のすべてのインスタンス化をBase
行うことです。これも避けたいと思います。ifとare not sameのf<T>
友達になりたいのですBase<T>
が、友達ではありません。同時に、クラス内での定義も提供したいと考えています。出来ますか?f<U>
Base<T>
U
T