gpt4 book ai didi

c++ - 是否允许复制/移动省略以使使用已删除函数的程序格式正确?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:17:32 28 4
gpt4 key购买 nike

考虑以下代码:

#include <iostream>

struct Thing
{
Thing(void) {std::cout << __PRETTY_FUNCTION__ << std::endl;}
Thing(Thing const &) = delete;
Thing(Thing &&) = delete;
Thing & operator =(Thing const &) = delete;
Thing & operator =(Thing &&) = delete;
};

int main()
{
Thing thing{Thing{}};
}

我希望 Thing thing{Thing{}}; 语句表示使用默认构造函数构造 Thing 类的临时对象并构造 thing Thing 类的对象使用刚刚创建的临时对象作为参数的移动构造函数。我希望这个程序被认为是错误的,因为它包含对已删除移动构造函数的调用,即使它可能被省略。标准的 class.copy.elision 部分似乎也要求这样做:

the selected constructor must be accessible even if the call is elided

Wording for guaranteed copy elision through simplified value categories似乎也不允许。

但是 gcc 7.2(还有 clang 4,但不是 VS2017 which still does not support guaranteed copy elision)将 compile this code just fine省略移动构造函数调用。

在这种情况下哪种行为是正确的?

最佳答案

它不会生成格式错误的程序。它完全摆脱了对已删除函数的引用。提案中的适当措辞如下:

[dcl.init] 子弹 17.6

If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object. [ Example: T x = T(T(T())); calls the T default constructor to initialize x. ]

这个例子进一步加强了这一点。因为它表明整个表达式必须折叠成一个默认结构。

需要注意的是,当由于值类别而删除拷贝时,删除的函数永远不会被 ODR 使用,因此程序不会引用它。

这是一个重要的区别,因为复制省略的其他形式仍然使用复制 c'tor,如下所述:

[basic.def.odr]/3

... A constructor selected to copy or move an object of class type is odr-used even if the call is actually elided by the implementation ([class.copy] ...

[class.copy] 描述了另一种允许的(但不是强制的)复制省略形式。如果我们在您的类里面演示:

Thing foo() {
Thing t;
return t; // Can be elided according to [class.copy.elision] still odr-used
}

应该使程序格式错误。 And GCC complains about it as expected .


顺便说一句。如果您认为在线编译器中的前一个示例是魔术师的把戏,并且 GCC 会提示,因为它需要调用 move c'tor。 Have a look at what happens when we supply a definition .

关于c++ - 是否允许复制/移动省略以使使用已删除函数的程序格式正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46071992/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com