我正在为我的项目开发一个小矢量类,基本上我不能从任何类型的数字构造一个矢量。即使它们都是不同的(例如Vector3(float,int,unsigned))。但是,我遇到了一个小问题,我迷失在这些模板及其顺序中。现在我的算术运算符无法正常工作。
这是矢量类的代码:
#include "Defines.hpp" // Typedefs for the fundamental types...
#include "Math/Base.hpp" // Various numerical functions...
template<class T, class Enable = void>
class Vector3;
template<class T>
class Vector3<T, typename std::enable_if<std::is_arithmetic<T>::value >::type>
{
public:
Vector3()
: X(0), Y(0), Z(0)
{
}
// explicit Vector3(T s)
// : X(s), Y(s), Z(s)
// {
//
// }
template <class U, typename std::enable_if<std::is_arithmetic<U>::value>::type* = nullptr>
explicit Vector3(U s)
: X(getBounded<T>(s)), Y(getBounded<T>(s)), Z(getBounded<T>(s))
{
}
// explicit Vector3(T x, T y, T z)
// : X(x), Y(y), Z(z)
// {
//
// }
template <class U1, typename std::enable_if<std::is_arithmetic<U1>::value>::type* = nullptr
, class U2, typename std::enable_if<std::is_arithmetic<U2>::value>::type* = nullptr
, class U3, typename std::enable_if<std::is_arithmetic<U3>::value>::type* = nullptr>
explicit Vector3(U1 x, U2 y, U3 z)
: X(getBounded<T>(x)), Y(getBounded<T>(y)), Z(getBounded<T>(z))
{
}
// explicit Vector3(const Vector3<T>& v)
// : X(v.X), Y(v.Y), Z(v.Z)
// {
//
// }
template <class U, typename std::enable_if<std::is_arithmetic<U>::value>::type* = nullptr>
explicit Vector3(const Vector3<U>& v)
: X(getBounded<T>(v.X)), Y(getBounded<T>(v.Y)), Z(getBounded<T>(v.Z))
{
}
explicit Vector3(Vector3<T>&& v)
: X(v.X), Y(v.Y), Z(v.Z)
{
}
// --------------------------------------------------------------------------------------------
~Vector3()
{
}
// --------------------------------------------------------------------------------------------
Vector3<T> & operator= (const Vector3<T> & v)
{
this->X = v.X;
this->Y = v.Y;
this->Z = v.Z;
return *this;
}
Vector3<T> & operator= (Vector3<T>&& v)
{
this->X = v.X;
this->Y = v.Y;
this->Z = v.Z;
return *this;
}
template <class U, typename std::enable_if<std::is_arithmetic<U>::value>::type* = nullptr>
Vector3<T> & operator= (const Vector3<U> & v)
{
this->X = getBounded<T>(v.X);
this->Y = getBounded<T>(v.Y);
this->Z = getBounded<T>(v.Z);
return *this;
}
// --------------------------------------------------------------------------------------------
public:
T X, Y, Z;
};
template <class T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr
, class U, typename std::enable_if<std::is_arithmetic<U>::value>::type* = nullptr>
Vector3<T> operator+ (const Vector3<T> & v, const U & s)
{
return Vector3<T>(v.X + getBounded<T>(s), v.Y + getBounded<T>(s), v.Z + getBounded<T>(s));
}
template <class T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr
, class U, typename std::enable_if<std::is_arithmetic<U>::value>::type* = nullptr>
Vector3<T> operator+ (const T & s, const Vector3<U> & v)
{
return Vector3<T>(s + getBounded<T>(v.X), s + getBounded<T>(v.Y), s + getBounded<T>(v.Z));
}
template <class T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr
, class U, typename std::enable_if<std::is_arithmetic<U>::value>::type* = nullptr>
Vector3<T> operator+ (const Vector3<T> & va, const Vector3<U> & vb)
{
return Vector3<T>(va.X + getBounded<T>(vb.X), va.Y + getBounded<T>(vb.Y), va.Z + getBounded<T>(vb.Z));
}
typedef Vector3< Int8 > Vector3C;
typedef Vector3< Uint8 > Vector3UC;
typedef Vector3< Int16 > Vector3S;
typedef Vector3< Uint16 > Vector3US;
typedef Vector3< Int32 > Vector3I;
typedef Vector3< Uint32 > Vector3UI;
typedef Vector3< Int64 > Vector3L;
typedef Vector3< Uint64 > Vector3UL;
typedef Vector3< Float32 > Vector3F;
typedef Vector3< Float64 > Vector3D;
当前构造函数已注释掉,我收到此错误:
||=== Build: Win32 Release in Sandbox (compiler: GNU GCC Compiler) ===|
..\source\Math\Vector3.hpp||In instantiation of 'Vector3<T> operator+(const Vector3<T>&, const Vector3<U>&) [with T = int; typename std::enable_if<std::is_arithmetic<_Tp>::value>::type* <anonymous> = 0u; U = unsigned char; typename std::enable_if<std::is_arithmetic<U>::value>::type* <anonymous> = 0u]':|
(...)\sandbox\main.cpp|#|required from here|
..\source\Math\Vector3.hpp|#|error: use of deleted function 'constexpr Vector3<int>::Vector3(const Vector3<int>&)'|
..\source\Math\Vector3.hpp|#|note: 'constexpr Vector3<int>::Vector3(const Vector3<int>&)' is implicitly declared as deleted because 'Vector3<int>' declares a move constructor or move assignment operator|
||=== Build failed: 1 error(s), 4 warning(s) (0 minute(s), 0 second(s)) ===|
当我在错误消息中取消注释所需的复制构造函数时,我会收到另一个错误,依此类推。
一切正常,直到我到达重载的算术运算符:
Vector3I v1(123343, -2143423, 12.35352f);
printf("%i, %i, %i\n", v1.X, v1.Y, v1.Z);
Vector3UC v2(v1);
printf("%i, %i, %i\n", v2.X, v2.Y, v2.Z);
v2 = v1 + v2; // If I comment this out then it works.
printf("%i, %i, %i\n", v2.X, v2.Y, v2.Z);
答案 0 :(得分:5)
在vector3的声明中:
explicit Vector3(Vector3<T>&& v)
: X(v.X), Y(v.Y), Z(v.Z)
{
}
你使Vector3的移动构造函数显式化,这意味着它不能被隐式调用。
这句话:
v2 = v1 + v2;
v1 + v2会创建一个临时对象,这里需要一个隐式移动构造函数来构造左边的v2,这就是编译错误发生的原因,请删除移动构造函数中的显式关键字。
移动构造函数的一个很好的例子是here