【发布时间】:2014-01-02 04:14:15
【问题描述】:
我有这个代码:
template<typename T1, typename T2>
auto operator*(const T1& a, const T2& b) -> decltype(viennacl::linalg::prod(a, b)) {
return viennacl::linalg::prod(a, b);
}
template<typename T1, typename T2>
auto operator*(const T1& a, const T2& b) -> decltype(prod(a, b)) {
return prod(a, b);
}
viennacl::linalg::prod 和prod 是两个不同的函数(也可以模板化)。
我认为如果某些模板函数定义不能用于某些类型,编译器会默默地忽略它并尝试另一个定义。有错吗?
Clang 3.3 编译良好,一切正常。然而 GCC 4.9 会抛出这个错误:
mathutils.hpp:77:6: error: redefinition of 'template<class T1, class T2> decltype (prod(a, b)) operator*(const T1&, const T2&)'
auto operator*(const T1& a, const T2& b) -> decltype(prod(a, b)) {
^
mathutils.hpp:72:6: note: 'template<class T1, class T2> decltype (viennacl::linalg::prod(a, b)) operator*(const T1&, const T2&)' previously declared here
auto operator*(const T1& a, const T2& b) -> decltype(viennacl::linalg::prod(a, b)) {
^
那么,哪个编译器出错了?
可能的解决方法是什么? (如果不清楚我想做什么:我想实现operator*,以便它使用viennacl::linalg::prod 或prod,具体取决于其中哪一个提供了实现。)
小型独立测试用例:
namespace X {
template<typename T> struct Mat{};
template<typename T> struct MatExpr {};
template<typename T>
MatExpr<T> prod(Mat<T> const& A, Mat<T> const& B) { return MatExpr<T>(); }
};
struct Mat2 {};
template<typename T>
X::Mat<T> prod(X::Mat<T> const& A, Mat2 const& B) { return X::Mat<T>(); }
template<typename T1, typename T2>
auto operator*(const T1& a, const T2& b) -> decltype(X::prod(a, b)) {
return X::prod(a, b);
}
template<typename T1, typename T2>
auto operator*(const T1& a, const T2& b) -> decltype(prod(a, b)) {
return prod(a, b);
}
int main() {}
我将上游报告为 GCC here 中的一个错误。
【问题讨论】:
-
对于相同的T1和T2,这两种decltype给出的具体类型是什么?如果它们相同,我希望它会像您一样发出消息。
-
prod和viennacl::linalg::prod永远不会同时工作,它总是要么是第一个要么是后者;甚至在这两种情况下都没有定义 decltype 。此外,错误不会在使用时发生,错误在编译器解析定义时已经发生。 -
您构建 SSCCE 的任何更改?
标签: c++ templates c++11 g++ clang++