C ++没有看到复制构造函数

时间:2014-08-05 14:09:08

标签: c++ templates c++11 constructor

我正在为我的项目开发一个小矢量类,基本上我不能从任何类型的数字构造一个矢量。即使它们都是不同的(例如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);

1 个答案:

答案 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