模板化中友元运算符的多个定义 class
Multiple definitions of friend operator in templated class
我有以下代码片段:
template < typename T1, typename T2 >
class Test
{
public:
Test() = default;
private:
template < typename T1_, typename T2_ >
friend Test< T1_, T2_ > operator*( const Test< T1_, T2_ >& lhs, const Test< T1_, T2_ >& rhs )
{
return Test< T1_, T2_ >();
}
};
int main( int argc, char* argv[] )
{
{
Test< int, int > t1;
Test< int, int > t2;
Test< int, int > t3 = t1 * t2;
}
{
Test< double, double > t1;
Test< double, double > t2;
Test< double, double > t3 = t1 * t2;
}
}
使用 clang 3.9 代码编译正常,使用 gcc 6.3.1 我得到以下错误:
redefinition of ‘template<class T1_, class T2_> Test<T1_, T2_> operator*(const Test<T1_, T2_>&, const Test<T1_, T2_>&)’
friend Test< T1_, T2_ > operator*( const Test< T1_, T2_ >& lhs, const Test< T1_, T2_ >& rhs )
哪个编译器是正确的?
如果是我怀疑的 gcc,我如何才能在-class 中正确声明模板化运算符*。 In-class 定义对我来说是参数依赖查找所必需的。
GCC 是正确的,因为 Test
的每个实例化都定义了模板 operator*
,它们是相同的,因为它们的签名不依赖于 T1
或 T2
。 operator*
在这里不需要是模板,只是 Test
:
的特定实例化的重载
template < typename T1, typename T2 >
class Test
{
friend Test operator*(const Test& lhs, const Test& rhs)
{
return Test();
}
};
int main( int argc, char* argv[] )
{
{
Test< int, int > t1;
Test< int, int > t2;
Test< int, int > t3 = t1 * t2;
}
{
Test< double, double > t1;
Test< double, double > t2;
Test< double, double > t3 = t1 * t2;
}
}
这将改为定义 operator*
的两个 non-template 重载,一个用于 Test
的每个实例化。
我有以下代码片段:
template < typename T1, typename T2 >
class Test
{
public:
Test() = default;
private:
template < typename T1_, typename T2_ >
friend Test< T1_, T2_ > operator*( const Test< T1_, T2_ >& lhs, const Test< T1_, T2_ >& rhs )
{
return Test< T1_, T2_ >();
}
};
int main( int argc, char* argv[] )
{
{
Test< int, int > t1;
Test< int, int > t2;
Test< int, int > t3 = t1 * t2;
}
{
Test< double, double > t1;
Test< double, double > t2;
Test< double, double > t3 = t1 * t2;
}
}
使用 clang 3.9 代码编译正常,使用 gcc 6.3.1 我得到以下错误:
redefinition of ‘template<class T1_, class T2_> Test<T1_, T2_> operator*(const Test<T1_, T2_>&, const Test<T1_, T2_>&)’
friend Test< T1_, T2_ > operator*( const Test< T1_, T2_ >& lhs, const Test< T1_, T2_ >& rhs )
哪个编译器是正确的?
如果是我怀疑的 gcc,我如何才能在-class 中正确声明模板化运算符*。 In-class 定义对我来说是参数依赖查找所必需的。
GCC 是正确的,因为 Test
的每个实例化都定义了模板 operator*
,它们是相同的,因为它们的签名不依赖于 T1
或 T2
。 operator*
在这里不需要是模板,只是 Test
:
template < typename T1, typename T2 >
class Test
{
friend Test operator*(const Test& lhs, const Test& rhs)
{
return Test();
}
};
int main( int argc, char* argv[] )
{
{
Test< int, int > t1;
Test< int, int > t2;
Test< int, int > t3 = t1 * t2;
}
{
Test< double, double > t1;
Test< double, double > t2;
Test< double, double > t3 = t1 * t2;
}
}
这将改为定义 operator*
的两个 non-template 重载,一个用于 Test
的每个实例化。