我有一堆模板化的结构(Vec3<T>
,Vec4<T>
,Mat4<T>
,...),并且我在做很多运算符重载。我已经将Mat4<T> * Vec4<T>
定义为通常的矩阵 vector 乘法。现在,我想将Vec4<T> * Mat4<T>
定义为逐行乘法。
我还使基础数据结构(我正在使用SIMD vector )受到保护,并且使结构的 friend 能够访问 protected data
字段。
问题是我想在operator*(const Vec4<T>&, const Mat4<T>&)
头文件中定义Mat4<T>
。通常,我要定义一个交换运算符是:
template<typename T>
Vec3<T> operator*(const T & s, const Vec3<T> & v)
{
return v * s;
}
但是在这种情况下,我必须更改行为,并且无法访问
Mat4<T>
和Vec4<T>
的 protected 成员。operator*(const Mat4<T>&)
是不完整的类型(可以在结构定义之后的Vec4<T>
header 中定义它),我可以将Mat4<T>
声明为Mat4<T>
成员吗? 注意:我想避免像
const typename Mat4<T>::MT & getData() const;
这样的公共(public)获取程序检索data
的不可变引用。解
@songyuanyao的答案对我来说几乎是正确的:
// In both Mat4 and Vec4
template<typename F>
friend Mat4<F> operator*(const Vec4<F> & v, const Mat4<F> & m);
最佳答案
是的,您可以将功能模板的特殊化声明为friend
。例如
// forward declaration
template<typename T>
class Vec4;
template<typename T>
class Mat4;
// declaration
template<typename T>
Vec4<T> operator*(const Vec4<T>&, const Mat4<T>&);
template<typename T>
class Vec4 {
// friend declaration
friend Vec4<T> operator* <T> (const Vec4<T>&, const Mat4<T>&);
...
};
template<typename T>
class Mat4 {
// friend declaration
friend Vec4<T> operator* <T> (const Vec4<T>&, const Mat4<T>&);
...
};
// definition
template<typename T>
Vec4<T> operator*(const Vec4<T>&, const Mat4<T>&)
{
...
}