【发布时间】:2011-04-22 09:31:59
【问题描述】:
我目前正在开发一个使用表达式模板的数值库。不幸的是,我遇到了运算符重载的问题。考虑以下精简示例。
#include <vector>
namespace test {
class test {};
template<class A, class B>
class testExpr {};
template<class A, class B>
testExpr<A, B>
operator-(A a, B b)
{
return testExpr<A, B>();
}
}
test::test
stuff(std::vector<test::test> &v)
{ return v.back(); }
int main()
{ }
在使用 gcc 4.4.3 或 clang 2.8 编译时会给出以下错误消息:
In file included from eir_test.cc:2:
In file included from /usr/include/c++/4.4/vector:64:
/usr/include/c++/4.4/bits/stl_vector.h:696:16: error: indirection requires pointer operand
('testExpr<__gnu_cxx::__normal_iterator<test::test *, std::vector<test::test, std::allocator<test::test> > >, int>' invalid)
{ return *(end() - 1); }
^~~~~~~~~~~~
eir_test.cc:21:12: note: in instantiation of member function 'std::vector<test::test, std::allocator<test::test> >::back' requested here
return v.back();
^
1 error generated.
由于某种原因,编译器会查找测试命名空间并找到我的通用运算符。我将这种形式与一些特质魔法一起使用,以减少我必须为操作员制作的版本数量。它应该接受 4 种不同的数据类型(包括 double 和 int),这会导致很多不同的组合。
有没有办法在不为每个运算符拼出所有组合的情况下完成这项工作?
【问题讨论】:
-
您的精确示例是否无法编译?我能够在 g++ 4.4.1 上很好地编译它。
-
错误信息来自 clang。 g++ 在那里也失败了,但错误消息更糟。我还尝试了 gcc 版本 4.3.4 (Ubuntu 4.3.4-10ubuntu1) 和 gcc 版本 4.1.3 20080704 (prerelease) (Ubuntu 4.1.2-27ubuntu1)。两者都失败了。
-
使用 gcc 3.4.6 失败,使用 gcc 4.4.1 编译,使用 gcc 4.4.4、gcc 4.5.2、gcc 4.6-alpha 失败。错误是一样的(在vector::iterator和一个int之间的operator-的结果上没有operator*)
标签: c++ templates stl operator-overloading expression-templates