我发现GCC 7实现了有保证的复制省略,我在魔杖盒中尝试了下面的代码
#include <iostream>
struct NonMovable
{
NonMovable() noexcept = default;
NonMovable(NonMovable&&) noexcept = delete;
NonMovable& operator=(NonMovable&&) noexcept = delete;
};
NonMovable Make()
{
return {};
}
int main()
{
//[[maybe_unused]] const auto x = Make();
//const auto z = NonMovable{};
[[maybe_unused]] const auto y = NonMovable{NonMovable{}};
}我得到了编译错误:
prog.cc: In function 'int main()':
prog.cc:20:60: error: use of deleted function 'NonMovable::NonMovable(NonMovable&&)'
[[maybe_unused]] const auto y = NonMovable{NonMovable{}};
^
prog.cc:6:5: note: declared here
NonMovable(NonMovable&&) noexcept = delete;
^~~~~~~~~~根据优先选择
在初始化过程中,如果初始化器表达式是prvalue,且源类型的cv非限定版本与目标类相同,则初始化器表达式用于初始化目标对象:
T x = T(T(T())); // only one call to default constructor of T, to initialize x
所以我认为它应该等于const Movable y{};。怎么了?
发布于 2016-10-07 16:10:16
列表初始化使您无法精确控制发生的事情。基本上,委员会已经猜到了程序员最可能想做的事情,并给出了相应的含义。
如果您想拥有精确的控制,请使用非列表初始化。因此,你的测试案件应该是绝对有效的。
如果您坚持列表初始化,那么对于聚合,我认为当前的草案措辞将做到这一点,并应用保证复制“省略”,因为他们说。
如果T是聚合类,初始化程序列表具有cv U类型的单个元素,其中U是T或从T派生的类,则从该元素初始化对象(复制列表初始化的复制初始化或直接列表初始化的直接初始化)。
此外,您可能在将来的标准修订版或缺陷报告解析中得到您想要的东西,甚至对于非聚合类也是如此。我相信你的类是一个集合,所以它应该编译。但也许我在这里遗漏了什么。
https://stackoverflow.com/questions/39920939
复制相似问题