我有一个带有重载朋友运算符的模板。它工作得很好,但如果在一个范围内有另一个不相关但相似的运算符,它不会编译:g++ 产生奇怪的错误,icc 和 MSVC 产生类似的错误。
代码是:
template <class Type> class product {};
template <> class product<double> { public: typedef double type; };
template<class Type> class product2 {
public: typedef typename product<Type>::type type;
};
//------------
template <class Cmpt> class Tensor { };
template <class Cmpt>
typename product2<Cmpt>::type operator&
(const Tensor<Cmpt>& a, const Tensor<Cmpt>& b)
{ return 0; } // [1]
//template <class Cmpt>
//typename product<Cmpt>::type operator&
//(const Tensor<Cmpt>& a, const Tensor<Cmpt>& b)
//{ return 0; }
//-----
template<class Type> class fvMatrix;
template<class Type>
fvMatrix<Type> operator&
(const fvMatrix<Type>& a, const fvMatrix<Type>& b)
{ return a; }
template <class Type> class fvMatrix {
friend fvMatrix<Type> operator& <Type>
(const fvMatrix<Type>& a, const fvMatrix<Type>& b);
};
//----------
int main() {
fvMatrix<int> m;
m & m;
return 0;
}
gcc 4.8.1 的错误是(类似于 4.8.0 和 4.7.2):
c.cpp: In instantiation of 'class product2<int>':
c.cpp:13:31: required by substitution of 'template<class Cmpt> typename product2<Type>::type operator&(const Tensor<Cmpt>&, const Tensor<Cmpt>&) [with Cmpt = int]'
c.cpp:32:27: required from 'class fvMatrix<int>'
c.cpp:39:17: required from here
c.cpp:5:50: error: no type named 'type' in 'class product<int>'
public: typedef typename product<Type>::type type;
icc 和 MSVC 会产生类似的错误(即尝试使用product<int>::type
via operator&
for )。Tensor<int>
如果我更改代码以便product
使用它或product2
用于operator&
(Tensor
取消注释注释行和注释运算符 [1]),则代码编译。
Tensor
如果我用它完全删除类operator&
,代码就会编译。
更新:完全删除m&m;
行仍然使代码无法编译。
我看到许多消息来源建议写作,friend fvMatrix<Type> operator& <>
即没有Type
之间<>
(http://www.parashift.com/c++-faq-lite/template-friends.html,C++模板友元运算符重载),这确实解决了这个问题。
然而,即使是https://stackoverflow.com/a/4661372/3216312上的评论也使用friend std::ostream& operator<< <T>
所以,问题是:为什么上面的代码不能编译?写错friend fvMatrix<Type> operator& <Type>
了,为什么?
背景:我们正在修改 OpenFOAM 框架,并在使用的原始 OpenFOAM 代码中遇到了这样的问题friend ... operator& <Type>
(http://foam.sourceforge.net/docs/cpp/a04795_source.html,第 484 行)。