我在这里遇到了一个令人困惑的问题,到目前为止我找不到任何解决方案: 链接器抱怨重载的非成员运算符==的多重定义。 想象一下以下情况:
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 specialization上面会导致错误:
Error : specialization of 'MyPtr<char>' after instantiation
Error : redefinition of 'class MyPtr<char>'
请注意我必须使用GCC 4.1.2。我希望它不是编译器问题......再次......
答案 0 :(得分:1)
如果出现以下情况,函数定义应仅出现在头文件中:
inline
关键字或(这些是ODR的多个相同定义版本适用的情况。)
因此模板函数通常不需要inline
。但是显式专门化实际上并没有任何模板参数,所以如果你想在头文件中将它标记为inline
。
答案 1 :(得分: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的更正