1

我在这里遇到了一个令人困惑的问题,到目前为止我找不到任何解决方案:链接器抱怨重载非成员运算符 == 的多重定义。想象以下情况:

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

这不应该

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

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

?

感谢 jogojapan 的更正

于 2013-05-29T14:48:06.807 回答
0

只有在以下情况下,函数定义才应出现在头文件中:

  • 它已使用inline关键字 OR声明
  • 它在类定义中定义,或者
  • 它涉及至少一个模板参数

(这些是 ODR 的多个相同定义版本适用的情况。)

因此inline,模板函数通常不需要。但是显式特化实际上并没有任何模板参数,所以inline如果你想在头文件中标记它,你应该标记它。

于 2013-05-29T14:56:58.353 回答