我碰到了有关此显式复制构造函数问题的墙。我一直在写一个类来弄清楚事情:

#include <iostream>

template<class T>
class Mat
{
private:
    T data;
public:
    void set(T value)
    {
        data = value;
    }

    Mat()
        : data(T(0))
    {
    }

    explicit Mat(const Mat& another)
    {
        *this = another;
    }

    Mat& operator=(const Mat& another)
    {
        data = another.data;
        return *this;
    }

    template<class U>
    explicit operator Mat<U>()
    {
        Mat<U> result;
        result.set(static_cast<U>(data));
        return result;
    }

    void print()
    {
        std::cout << data << std::endl;
    }
};


int main()
{
    Mat< double > d1;
    d1.set(3.14159);
    Mat< int > i1(static_cast<Mat<int>>(d1));
    d1.print();
    i1.print();

    std::cin.sync();
    std::cin.ignore();
    return 0;
}

我希望我的副本构造函数仅接受另一个对象的显式转换后的实例,因此我将其声明为显式的,但现在出现错误错误“C2558:类'Mat':没有可用的副本构造函数或副本构造函数被声明为'explicit'”,即使我做了一个明确的 Actor 表:
static_cast<Mat<int>>(d1)

我已经声明了复制构造函数是明确的,因为我希望这是非法的:
Mat<float> a;
Mat<int>   b(a);

同时,我希望以下内容保持合法:
Mat<float> a;
Mat<int>   b(static_cast<Mat<int>>(a));

编辑:我一直在尝试修改这些概念,试图确切地定义我想要得到的东西,而且我似乎得到了一些有趣的结果:
#include <iostream>

class MatB
{
private:
    float data;
public:
    MatB()
        :data(0.0f)
    {

    }

    void set(float value)
    {
        data = value;
    }

    float getData() const
    {
        return data;
    }

    void print()
    {
        std::cout << data << std::endl;
    }
};

class MatA
{
private:
    double data;
public:


    MatA()
        :data(0.0)
    {

    }

    void set(double value)
    {
        data = value;
    }

    double getData() const
    {
        return data;
    }

    explicit operator MatB()
    {
        MatB temp;
        temp.set(static_cast<float>(getData()));
        return temp;
    }

    void print()
    {
        std::cout << data << std::endl;
    }
};



class MatC
{
private:
    int data;
public:

    MatC()
        :data(0)
    {

    }

    explicit MatC(const MatB& in)
        :data(static_cast<int>(in.getData()))
    {

    }

    void print()
    {
        std::cout << data << std::endl;
    }
};

int main()
{
    MatA someA;
    someA.set(3.14159);
    MatC constructCFromA(someA);
    someA.print();
    constructCFromA.print();

    std::cin.sync();
    std::cin.ignore();
    return 0;
}

在此示例中,constructCFromA(someA)不应编译(imo)-即使链接程序将其标记为错误(VS2013),也仍然可以编译...我不确定我对“显式”的理解是否不正确, IDE是否将其错误地标记为错误,还是编译器将其编译为正确的错误。我以为我需要做这样的事情:
constructCFromA(static_cast<MatB>(someA));

IDE似乎同意我的观点,但是编译器不同意。我必须说我很困惑。

编辑2:
没关系,在Ideone中它不会编译,所以我想应该归咎于MS。
我认为第二个代码很好地说明了我想要得到的行为。基本上将初始化和分配时的非显式转换设为非法。但是,使复制构造函数显式出现似乎有各种“副作用”。

最佳答案

您进行显式强制转换的行不是问题。导致编译问题的问题在于按值返回Mat<U>的行:

template<class U>
explicit operator Mat<U>()
{
    Mat<U> result;
    result.set(static_cast<U>(data));
    return result;  // <<== This line requires a copy constructor to be defined
}

这就是为什么当您在复制ctor之前删除explicit时,您的代码可以正常工作的原因。

关于c++ - C++显式复制构造函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27657993/

10-12 15:03