【发布时间】:2011-12-22 10:42:01
【问题描述】:
你们怎么了,
我正在尝试为我的数学向量类重载加法运算符。 我的(看似逻辑正确)简化代码是:
template<typename T>
class Vector2
{
private:
T m_data[2];
template<typename U>
friend auto operator+(Vector2<T> a, Vector2<U> b) -> Vector2<decltype(a.m_data[0] + b.m_data[0])>
{
Vector2<decltype(a.m_data[0] + b.m_data[0])> ret( a.m_data[0] + b.m_data[0],
a.m_data[1] + b.m_data[1] );
return ret;
}
public:
inline Vector2(T x, T y)
{
m_data[0] = x;
m_data[1] = y;
}
};
int main()
{
Vector2<float> v1(0.5f, 0.5f);
Vector2<float> v2(1, 2);
v2 + v1; // Line 29
return 0;
}
但是,GCC 4.6.1 给了我这个:
W:\projects\Awesome\BetterStuff\main.cpp||In function 'Vector2<decltype ((a.m_data[0] + b.m_data[0]))> operator+(Vector2<T>, Vector2<U>) [with U = float; T = float; decltype ((a.m_data[0] + b.m_data[0])) = float]':|
W:\projects\Awesome\BetterStuff\main.cpp|5|error: 'float Vector2<float>::m_data [2]' is private|
W:\projects\Awesome\BetterStuff\main.cpp|29|error: within this context|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 0 seconds) ===|
如果我将第二个向量更改为 int 向量,则会出现更多(类似)错误。
我最接近解决这个问题的方法是找到这个有趣的页面:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48884
但遗憾的是,我不能用它来解决我自己的问题。 我尝试了 GCC 4.6.2 和 4.7.0,但我的代码也没有编译。
将“private”改为“public”确实解决了我的问题,但显然我的意图不是暴露m_data;
我只想定义一个加法运算符,它的返回类型由模板参数确定,据我了解,这是编译时的事情-对于模板函数的每个实例化,编译器都会自动计算出基于返回类型在 decltype() 那里。我的意思是,main() 以哪种方式尝试访问这些向量之一的 m_data 的内容?
这整件事让我很困惑,任何帮助将不胜感激。
好的,谢谢
【问题讨论】:
-
如果有人感兴趣,因为我使用数字类型(具有 0 参数构造函数)作为 Vector2 的模板参数,我想我可以用这个替换旧的 decltype:decltype(T () + U())。虽然编译器为什么讨厌我的代码,但我仍然很感兴趣。
-
有趣的是,如果 v1 和 v2 都是浮点数(即相同的类型),decltype(T() + U()) 工作。至少它适用于4.7。它仍然不适用于 float + int。
标签: c++ templates c++11 private decltype