1

ここで紛らわしい問題に行き詰まり、これまでのところ解決策が見つかりませんでした。リンカは、オーバーロードされた非メンバー operator== の複数の定義について不平を言っています。次の状況を想像してください。

template <class T>
struct MyPtr
{
  T* val;
  ...
}

template <class T> bool operator==(MyPtr<T> const & lhs, MyPtr<T> const & rhs)
{ return *lhs.val == *rhs.val; }
template <class T> bool operator==(MyPtr<T> const & lhs, T* const & rhs)
{ return *lhs.val == *rhs;}

これまでのところ、すべてが魅力のように機能しますが、特定の方法で char* に反応するようにクラスを特殊化しようとすると、奇妙なことが起こります:

template <>
struct MyPtr<char>
{
  char* val;
  ...
}

//Now each of these functions result in a multiple definition error of the Linker, 
//and i dont get why:
//bool operator== (MyPtr<char> const& lhs, MyPtr<char> const& rhs)
//{ return strcmp(lhs.val,rhs.val) == 0;}

//template <> bool operator==<char> (MyPtr<char> const& lhs, MyPtr<char> const& rhs)
//{ return strcmp(lhs.val,rhs.val) == 0;}

それで、私はここで何が間違っていますか?私のコードの順序は、ここに書かれているとおりです。これらの関数定義を Class 特殊化の上に移動すると、エラーが発生します。

Error : specialization of 'MyPtr<char>' after instantiation
Error : redefinition of 'class MyPtr<char>'

GCC 4.1.2 を使用する必要があることに注意してください。ここでコンパイラの問題ではないことを願っています...再び...

4

2 に答える 2

0

関数定義は、次の場合にのみヘッダー ファイルに表示する必要があります。

  • inlineキーワード ORで宣言されている
  • クラス定義内で定義されている、または
  • 少なくとも 1 つのテンプレート パラメータが含まれます

(これらは、ODR の複数同一定義バージョンが適用されるケースの 1 つです。)

したがってinline、通常、テンプレート関数では必要ありません。ただし、明示的な特殊化には実際にはテンプレート パラメーターがないためinline、ヘッダー ファイルで必要な場合はマークする必要があります。

于 2013-05-29T14:56:58.353 に答える