这个回报声明中发生了什么?

Lor*_*ins 6 c++ stl

我正在阅读复制文章(以及它应该如何在C++ 17中得到保证),这让我有点困惑(我不确定我知道我以前认识的事情).所以这是一个最小的测试用例:

std::string nameof(int param)
{
    switch (param)
    {
    case 1: 
        return "1"; // A
    case 2: 
        return "2" // B
    }
    return std::string(); // C
}
Run Code Online (Sandbox Code Playgroud)

我看到它的方式,情况A和B对返回值执行直接构造,因此复制省略在这里没有意义,而案例C不能执行复制省略,因为有多个返回路径.这些假设是否正确

另外,我想知道是否

  • 有写了上一个更好的方法(例如有一个std::string retval;总是返回一个或写入的情况下A,并B作为return string("1")等)
  • 有任何移动发生,例如"1"是暂时的,但我假设它被用作构造函数的参数std::string
  • 我有一个优化问题(例如我认为C可以写成return{},这会是一个更好的选择吗?)

Ser*_*eyA 3

为了使其对 NRVO 友好,您应该始终返回相同的对象。对象的值可能不同,但对象应该是相同的。

然而,遵循上述规则会使程序更难阅读,并且通常应该选择可读性而不是不明显的性能改进。由于std::string定义了移动构造函数,移动指针和长度与不移动指针和长度之间的差异非常小,以至于我在应用程序中看不到真正注意到这一点的方法。

至于你的最后一个问题,return std::string()return {}是完全一样的。

你的问题中也有一些不正确的表述。例如,"1"不是临时的。这是一个字符串文字。Temporary 是根据这个文字创建的。

最后但并非最不重要的一点是,强制 C++17 复制省略在这里不适用。它是为类似的情况保留的

std::string x = "X";
Run Code Online (Sandbox Code Playgroud)

在强制要求之前,可以生成代码来创建临时对象std::string并使用复制(或移动)构造函数进行初始化x