【发布时间】:2021-05-25 02:21:25
【问题描述】:
我有一个简单的类“vec2”。我希望这个类能够在类模板中存储双精度和双引用,甚至是 int 和 int 引用。这是所需的行为-
vec2<double> base(5, 5); //normal vec2
vec2<double&> reference(base.x, base.y); //vec2 reference to vec2 "base"
vec2<double> third;
base.x++; //base.x equals 6, this also changes reference.x to 6;
third = reference; //conversion between vec2<double> and vec2<double&>
我还希望修改 vec2 的引用实例是不可能的,除非通过更改它引用的变量 - 所以下面的代码会给出编译器错误
vec2<double&> reference(base.x, base.y); //vec2 reference to vec2 "base"
reference.x = 5; //undesired behaviour
有没有办法在处理非引用类类型时使成员 x 和 y 公开,但在类类型是引用时使成员私有?这将需要特定于何时返回 x 和 y 值的引用的方法。在参考版本中,它还需要没有可能影响参考的重载运算符方法。我稍微了解模板专业化,但还不足以真正实现它。
无论如何,这里的重点是找出如何获取vec2<double>类型的类,并将其转换为vec2<double&>类型的类。
或者,反过来,取一个 vec2<double&> 类型的类,并将其转换为 vec2<double> 类型的类。
这是我的简单 vec2 类-
template <class T> class vec2{
public:
vec2(){
x = 0;
y = 0;
}
vec2(T X, T Y){
x = X;
y = Y;
}
void normalize(){ //this function should inaccesable to any "reference version" of vec2
*this /= magnitude();
}
void rotate(double radians, vec2 center){ //this should also be inaccesable to reference versions
vec2 ogPts = *this -= center;
x = ogPts.x*cos(radians) - ogPts.y*sin(radians);
y = ogPts.y*cos(radians) + ogPts.x*sin(radians);
*this += center;
}
double magnitude() const{
return sqrt(x * x + y * y); //this should be available to both
}
T x;
T y;
vec2 operator+(const vec2 &v) const{ //available to both
return vec2(x+v.x, y+v.y);
}
vec2 operator-(const vec2 &v) const{ //available to both
return vec2(x-v.x, y-v.y);
}
vec2 operator*(const vec2 &v) const{ //available to both
return vec2(x*v.x, y*v.y);
}
vec2 operator*(T v) const{ //available to both, but should work even if v is not a reference variable and T is a reference
return vec2(x*v, y*v);
}
vec2 operator/(T v) const{ //available to both, but should work even if v is not a reference variable and T is a reference
return vec2(x/v, y/v);
}
vec2 operator+=(const vec2 &v){ //inaccesable to reference versions of the class
x += v.x;
y += v.y;
return *this;
}
vec2 operator-=(const vec2 &v){ //inaccesable to reference versions
x -= v.x;
y -= v.y;
return *this;
}
vec2 operator*=(const vec2 &v){ //inaccesable to reference versions
x *= v.x;
y *= v.y;
return *this;
}
vec2 operator*=(T v){ //inaccesable to reference versions
x *= v;
y *= v;
return *this;
}
vec2 operator/=(T v){ //inaccesable to reference versions
x /= v;
y /= v;
return *this;
}
bool operator==(const vec2 &v) const{ //this should be available to both
return (v.x == x && v.y == y);
}
bool operator!=(const vec2 &v) const{ //this should be available to both
return (v.x != x || v.y != y);
}
};
非常感谢任何帮助!我没有太多使用模板,事实上,我昨天才开始!提前感谢您的宝贵时间!
【问题讨论】:
-
听起来您的引用类型应该是完全不同的类模板。我很困惑
vec2<T>会有公共或私有数据成员以及不同的功能,具体取决于T是什么。也许做一个vec2ref<T>?或者更好的是,摆脱它并使用const vec2<T>& -
@Kevin 我不认为它应该是一个不同的类......这看起来很丑陋。不能为不同的模板类型实现不同的方法吗?如果能够互换使用 vec2
和 vec2 那就太好了。我不认为 const vec2 & 完全符合我的要求,因为我希望能够使用任何引用类型作为 x 和 y 成员,而 const vec2 & 只允许vec2 的参考。如果我想使用 int x 和 int y 作为参考怎么办?不可能像使用 vec2 那样一步完成。
标签: c++ templates type-conversion template-specialization