我有一个由EulerAngle类继承的Vector类。我希望能够在EulerAngle对象上使用Vector类中的运算符,而不必重写EulerAngle类中的运算符,并尽可能将Vector3更改为Angle。我该怎么办?
class Vector3 {
public:
float x, y, z;
// ctors...
__forceinline Vector3() : x{}, y{}, z{} {
__forceinline Vector3( float x, float y, float z ) : x{ x }, y{ y }, z{ z } {
}
// functions...
// operators...
__forceinline Vector3 &operator +=( const Vector3 &other ) {
x += other.x;
y += other.y;
z += other.z;
return *this;
}
__forceinline Vector3 &operator +=( float scalar ) {
x += scalar;
y += scalar;
z += scalar;
return *this;
}
__forceinline Vector3 operator +( float scalar ) const {
return Vector3( x + scalar, y + scalar, z + scalar );
}
__forceinline Vector3 operator +( const Vector3 &other ) const {
return Vector3( x * other.x, y * other.y, z * other.z );
}
}
class EulerAngle : public Vector3 {
private:
};
// example, MSVC says this is an error and that there is no suitable conversion from EulerAngle to Vector3
EulerAngle ang = { 1.f, 1.f, 1.f };
ang += 5.f
在回答了几个问题之后,我添加了以下代码以使其工作。但是我仍然想知道是否有更好的方法来实现这一目标?
class EulerAngle : public Vector3 {
public:
using Vector3::Vector3;
__forceinline EulerAngle( const Vector3 &other ) : Vector3( other ) {
}
};
答案 0 :(得分:2)
当Vector3
不继承自Vector3
时,您可以使用template<typename T>
operator T() const
{
static_assert(std::is_base_of<Vector3, T>::value, "T is not inherited from Vector3");
return T{x,y,z};
}
中的user-defined conversion到想要的类型,并带有静态断言。
C++20
================================================ ================
通过template<typename T>
requires std::DerivedFrom<T,Vector3>
constexpr operator T() const
{
return T{x,y,z};
}
和concepts的引入,可以将以上代码重写为:
// error.h
struct ErrorInfo {};
template <class T>
const ErrorInfo& error(const T&);
// Found.h
struct Found
{
const char *begin, *end;
};
Found find(const char*,const char*);
struct Found_ErrorInfo : ErrorInfo
{
const char *type;
char fault[3];
unsigned index;
Found_ErrorInfo()
: type("Not found"), fault{'\e','w',0}, index(0) {};
~Found_ErrorInfo() { delete this; }
};
template <>
const ErrorInfo& error<Found>(const Found &f)
{
return *new Found_ErrorInfo();
}
// main.cpp
int main()
{
Found f = find("dada", "I love my mama");
if(f.begin != nullptr) std::cout << f.begin;
else const ErrorInfo &info = error(f);
}
答案 1 :(得分:0)
为Vector3
类中的using
构造函数从Vector3
和EulerAngle
添加隐式构造函数
class EulerAngle : public Vector3 {
using Vector3::Vector3;
EulerAngle(const Vector3& from) : Vector3(from) {}
}
如果您要这样做
EulerAngle ang = { 1.f, 1.f, 1.f };
ang += 5.f;
EulerAngle ang2 = ang + 5.f;
EulerAngle ang3 = Vector3{ 2.f, 2.f, 2.f } + ang2;