其他分享
首页 > 其他分享> > C不通过取消注释move运算符进行编译

C不通过取消注释move运算符进行编译

作者:互联网

我有以下代码:

template <typename T>
struct X {
    X() : x(5) {}

    template <template <typename> class S>
    X(const S<T> & y) : x(y.x) {}

    // Uncomment and it does not compile anymore
    // X(X&& z) : x(z.x) {}

    T x;
};

int main ()
{
    X<int> y;
    auto x = y;
    return 0;
}

你可以解释为什么一旦取消注释指定的代码就不能编译它?

解决方法:

Humam Helfawi明白了这一点.

我试着完成他的回答.

Svalorzen:看看这段代码

#include <iostream>

template <typename T>
struct X {
    X() : x(5) {}

    template <template <typename> class S>
    X (const S<T> & y) : x(y.x)
     { std::cout << "templated constructor" << std::endl; }

    X (const X<T> & y) : x(y.x)
     { std::cout << "copy constructor" << std::endl; }

    T x;
};

int main ()
{
    X<int> y;
    auto x = y;
    return 0;
}

输出是“复制构造函数”.

当编译器找到匹配的模板化函数和匹配的普通(无模板)函数时,请选择plain作为更具体的.

现在删除复制构造函数的定义

#include <iostream>

template <typename T>
struct X {
    X() : x(5) {}

    template <template <typename> class S>
    X (const S<T> & y) : x(y.x)
     { std::cout << "templated constructor" << std::endl; }

    T x;
};

int main ()
{
    X<int> y;
    auto x = y;
    return 0;
}

如果没有移动构造函数并添加了cout(“模板化构造函数”),你就可以得到你的例子.

您可以看到输出为空.

那是因为编译器选择了作为默认版本隐式存在的复制构造函数.

当您添加移动构造函数时,您偶然将标记为已删除的复制构造函数.但复制构造函数始终存在(即使标记为已删除),编译器也会考虑它.因此,当编译器尝试实现“x = y”时,匹配您的模板化构造函数,匹配复制构造函数,选择复制构造函数(更具体),看到它被删除并给出错误.

当你添加

X (const X<T> &) = default;

您允许编译器使用复制构造函数.

p.s:抱歉我的英语不好.

标签:move-constructor,c,c11,templates,copy-constructor
来源: https://codeday.me/bug/20190828/1757159.html