gpt4 book ai didi

c++ - 返回不可复制常量值的函数的不直观 RVO?

转载 作者:行者123 更新时间:2023-12-04 04:27:37 29 4
gpt4 key购买 nike

考虑以下 C++ >=17 中的示例代码:

struct A{
A() = default;
A(const A&) = delete;
};

const A f(){ return A{}; }

int main(){
const A& a = f(); // OK
// A& b = f(); // Error: cannot convert 'const A' to 'A&'
const A c = f(); // OK: Copy elision
A d = f(); // OK!?
}
类(class) A不可复制,但由于 mandatory copy-elision ,我们可以把 f()的结果成变量。根据 this page在 cppreference.com 中,上述行为是完全合法的,因为它指定了 const发生复制省略时,将忽略返回值上的量词。
然而,这种行为对我来说似乎非常违反直觉。自 A不可复制,感觉应该没办法转 const A进入 A (除非你有 A::A(const A&&) 构造函数)。这是一个深思熟虑的决定,还是被认为是语言规范中的缺陷?
(我在尝试实现自己的类型删除类时遇到了这个问题。我在函数 const 的返回值上指定 f() 的全部目的是为了防止用户获得非 const 左值引用的对象,但这个规范似乎打开了一个洞。)
编辑 :这个例子可能更清楚地展示了反直觉:让我们考虑一个类 A即可移动但不可复制。
struct A{
A() = default;
A(const A&) = delete;
A(A&&) = default;
};

int main(){
// C++14: move / C++17: copy elision
A a = A{};

// C++14: error (deleted copy constructor) / C++17: copy elision(!!)
A b = static_cast<const A>(A{});
}
This does not compile in C++ <=14, but compiles in C++ >=17.在类可移动但不可复制的常见情况下, const意味着在 C++14 之前没有办法从中获取非常量对象,但它不再是了(只要将 const 添加到纯右值中)。

最佳答案

这将是一个 更改为拒绝使用可移动对象进行此类初始化,因为该语言的先前版本会在那里产生移动。让它依赖于变量的 cv 限定是非常微妙的。
对于 可复制 对象,新行为实际上是一个 子集旧的:来自 const A 的拷贝返回值到 A变量可以被省略,在这种情况下,它们与 C++17 中的对象一样多。
同时,自 C++11 以来,const 返回值有些不受欢迎,其中 f(return_const())失去能力搬家转换为(按值)参数。
C++17 对纯右值的处理(“强制复制省略”是一个只在历史上有意义的名称)支持其他情况,例如返回 不可移动 本例中的对象:函数被认为指定如何初始化它“返回”的对象,而不是实际返回一个完成的对象。在选择此型号时,一般认为支持 更为重要。更多 种有效的代码,而不是支持防止滥用的现有习语。

关于c++ - 返回不可复制常量值的函数的不直观 RVO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67245700/

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