作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
大家好,
我正在尝试为我的数学 vector 类重载加法运算符。我的(看似逻辑正确的)简化代码是:
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) ===|
如果我将第二个 vector 更改为 int vector ,它会给我更多(类似的)错误。
我最接近弄清楚这件事的是找到这个有趣的页面:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48884
但遗憾的是,我不能用它来解决我自己的问题。我尝试了 GCC 4.6.2 和 4.7.0,但我的代码也没有编译。
将“private”改为“public”确实解决了我的问题,但显然我的意图不是暴露m_data;
我只想定义一个加法运算符,它的返回类型由模板参数决定,根据我的理解,这是一个编译时的事情——对于模板函数的每个实例,编译器会自动计算出基于返回类型在 decltype() 那里。我的意思是,main() 以哪种方式尝试访问这些 vector 之一的 m_data 的内容?
这整件事让我很困惑,任何帮助将不胜感激。
好的谢谢
最佳答案
嗯,GCC 是对的...问题不是 Vector2(float) 试图访问 Vector(int) 的私有(private)成员,而是 operator+(它只是Vector2(float)) 试图访问 Vector2(int) 的私有(private)成员。所以更新后的代码是:
template<typename T>
class Vector2
{
template<typename U>
friend class Vector2;
private:
T m_data[2];
template<typename T1, typename U>
friend auto operator+(Vector2<T1> a, Vector2<U> b) -> Vector2<decltype(a.m_data[0] + b.m_data[0])>;
public:
inline Vector2(T x, T y)
{
m_data[0] = x;
m_data[1] = y;
}
inline Vector2<T>& operator=(const Vector2<T>& vec)
{
m_data[0] = vec.m_data[0];
m_data[1] = vec.m_data[1];
}
};
template<typename T, typename U>
auto operator+(Vector2<T> a, Vector2<U> b) -> Vector2<decltype(a.m_data[0] + b.m_data[0])>
{
Vector2<decltype(T() + U())> ret( a.m_data[0] + b.m_data[0],
a.m_data[1] + b.m_data[1] );
return ret;
}
int main()
{
Vector2<float> v1(0.5f, 0.5f);
Vector2<int> v2(1, 2);
//Vector2<int> a = v2 + v1; // Doesn't work
Vector2<float> b = v2 + v1; // Works
return 0;
}
关于C++11 - 模板、友元、decltype 和访问修饰符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8016885/
我是一名优秀的程序员,十分优秀!