c++ - 为什么删除模板复制构造函数会导致赋值运算符功能失调?

标签 c++ templates copy-constructor delete-operator copy-assignment

我有如下代码,看起来有点令人困惑。我定义了一个模板类。它有一个用户定义的构造函数。当我通过“operator =”声明该模板类的两个对象时,令我惊讶的是它的用户定义构造函数被调用。另外,删除其复制构造函数后,在解析“operator =”时,编译甚至无法通过。模板构造函数与非模板类有不同的规则吗?

#include "iostream"
using namespace std;

template <typename T>
class MyPtr
{
private:
    T p_;
public:
    MyPtr(T P = NULL): p_(P)
    {
        cout<<"track!!"<<endl;
    }

    //MyPtr(const MyPtr<T> & P) = delete;
    ~MyPtr()
    {
 
    }
};

int main()
{
    int i=3;
    int j=4;
    MyPtr<int> p = i;
    MyPtr<int> pp = j;
}

最佳答案

Does templete constructors have different rules than non-templete class?

没有。

MyPtr<int> p = i; (和 MyPtr<int> pp = j; )是 copy initialization 。请注意,这是初始化,而不是赋值,效果为 p由构造函数 MyPtr::MyPtr(T) 初始化。例如

MyPtr<int> p = i; // initialization; constructors get called
p = j;            // assignment; assignment operators (operator=) get called

C++17 之前,i将转换为MyPtr<int>通过MyPtr::MyPtr(T)首先是转换结果,即临时的MyPtr<int>被复制/移动以初始化 p ;即使允许优化复制/移动操作,复制/移动构造函数也需要可访问。将复制构造函数声明为 delete使复制构造函数不可用,并且不会生成移动构造函数,从而使 MyPtr<int> p = i; C++17 之前格式错误。

由于 C++17,优化是强制性的,并且复制/移动构造函数不需要再次访问,这意味着您的代码可以在 C++17 模式下正常编译,即使将复制构造函数声明为 delete .

  • If T is a class type, and the cv-unqualified version of the type of other is not T or derived from T, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T (or to a type derived from T if T is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion, which is a prvalue temporary (until C++17) prvalue expression (since C++17) if a converting constructor was used, is then used to direct-initialize the object. The last step is usually optimized out and the result of the conversion is constructed directly in the memory allocated for the target object, but the appropriate constructor (move or copy) is required to be accessible even though it's not used. (until C++17)

关于c++ - 为什么删除模板复制构造函数会导致赋值运算符功能失调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66419314/

相关文章:

c++ - C++中复制构造函数的困惑

c++ - 斜齿轮结构 : Sweep Profile with Spin (twist)

c++ - MATLAB 中的 mysql.cpp 编译错误

c++ - 预处理器##粘贴运算符

HTML-CSS : Avoid Next Line Before Input Field

c++ - 调用复制构造函数时如何复制内存?

c++ - 混用 std: :'s and boost::' s::bind 和::function 会导致问题吗?

c++ - 为模板化( Armadillo )类专门化模板化函数

php - 如何在模块中使用 ExpressionEngine 表单验证类来重新填充模板中的表单?

c++ - std::string x(x);