【发布时间】:2014-02-06 12:26:06
【问题描述】:
我有一个带有重载友元运算符的模板。它工作得很好,但是如果一个范围内有另一个不相关但相似的运算符,它不会编译: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 会产生类似的错误(即尝试通过 operator& 使用 product<int>::type 来代替 Tensor<int>)。
如果我更改代码以便使用 product 或 operator& 中的 product2 代替 Tensor(取消注释注释行和注释运算符 [1]),则代码编译。
如果我完全删除类 Tensor 及其 operator&,则代码编译。
更新:完全删除 m&m; 行仍然导致代码无法编译。
我看到许多消息来源建议写friend fvMatrix<Type> operator& <>,即在<>(http://www.parashift.com/c++-faq-lite/template-friends.html,C++ template friend operator overloading)之间没有Type,这确实解决了这个问题。
然而,即使https://stackoverflow.com/a/4661372/3216312 的评论使用friend std::ostream& operator<< <T>
那么,问题是:为什么上面的代码不能编译?写friend fvMatrix<Type> operator& <Type> 错了吗?为什么?
背景:我们正在修改 OpenFOAM 框架,并在使用 friend ... operator& <Type>(http://foam.sourceforge.net/docs/cpp/a04795_source.html,第 484 行)的原始 OpenFOAM 代码中遇到了这样的问题。
【问题讨论】:
-
clang 3.4 也出现错误
标签: c++ templates friend sfinae template-argument-deduction