相关疑难解决方法(0)

将返回的左值隐式处理为右值

12.8复制和移动类对象[class.copy]§31和§32说:

在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cv-unqualified类型的非易失性自动对象(函数或catch子句参数除外)的名称时,通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作

当满足或将满足复制操作的省略标准时,除了源对象是函数参数这一事实,并且要复制的对象由左值指定,重载决策选择复制的构造函数是首先执行,好像对象是由右值指定的.

因此我们可以写:

unique_ptr<int> make_answer()
{
    unique_ptr<int> result(new int(42));
    return result;   // lvalue is implicitly treated as rvalue
}
Run Code Online (Sandbox Code Playgroud)

但是,我注意到g ++ 4.6.3也接受不是名称的左值,例如:

    return (result);
    return *&result;
    return true ? result : result;
Run Code Online (Sandbox Code Playgroud)

相比之下,return rand() ? result : result;不起作用.编译器的优化器是否会干扰语言语义?当我解释标准时,return (result);不应该编译,因为(result)它不是名称,而是带括号的表达式.我是对还是错?

c++ return move-semantics c++11

19
推荐指数
1
解决办法
563
查看次数

copy elision:在return语句中使用三元表达式时调用未调用的构造函数?

请考虑以下示例:

#include <cstdio>

class object
{
public:
    object()
    {
        printf("constructor\n");
    }

    object(const object &)
    {
        printf("copy constructor\n");
    }

    object(object &&)
    {
        printf("move constructor\n");
    }
};

static object create_object()
{
    object a;
    object b;

    volatile int i = 1;

// With #if 0, object's copy constructor is called; otherwise, its move constructor.
#if 0
    if (i)
        return b; // moves because of the copy elision rules
    else
        return a; // moves because of the copy elision rules
#else
    // Seems equivalent …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

9
推荐指数
1
解决办法
791
查看次数

何时返回函数外部的值使用move vs copy?

看完这个问题后.我创建了这个小小的测试:

class A{
public:
    A(){}
    A(const A&){printf("copy\n");}
    A(A&&){printf("move\n");}

    static A f(){
        A a;
        return a;}

    static A g(){
        A a;
        return (a);}//could be return *&a; too.

    static A h(){
        A a;
        return true?a:a;}

 };
Run Code Online (Sandbox Code Playgroud)

结果是(没有RVO和NRVO):

  • f使用移动
  • g使用移动
  • h使用副本

据我所知,用于决定是否使用复制或移动的规则在12.8.32中描述:

  • 满足或将满足复制操作的省略标准时,除了源对象是函数参数这一事实,并且要复制的对象由左值指定,重载决策选择复制的构造函数是首先执行,好像对象是由右值指定的....

这是指12.8.31的规则:(我只显示相关部分)

  • 在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cvunqualified类型的非易失性自动对象(函数或catch子句参数除外)的名称时,副本通过将自动对象直接构造到函数的返回值中,可以省略/ move操作
  • 当一个未绑定到引用(12.2)的临时类对象被复制/移动到具有相同cv-nonqualified类型的类对象时,可以通过将临时对象直接构造到目标中来省略复制/移动操作省略的复制/移动

按照这些规则,我理解f和h会发生什么:

  • f中的副本有资格获得elision,因此被移动.(参见粗体部分)
  • h中的副本不符合elision的条件,因此会被复制.

怎么样?

对我来说,它看起来很像h.我正在返回一个表达式,它不是自动对象的名称,因此我认为它会被复制但是它被移动了.这里发生了什么?

c++ copy return move c++11

8
推荐指数
1
解决办法
446
查看次数

为什么以下代码不调用std :: string的移动构造函数?

在VS2013上编译的以下代码从不调用std :: string的移动构造函数(通过设置断点检查,而是调用const ref复制构造函数.

#include <iostream>
#include <string>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */

struct foo
{
    foo(std::string& str1, std::string& str2) : _str1(str1), _str2(str2) {}

    ~foo() { std::cout << "Either \"" << _str1 << "\" or \"" << _str2 << "\" was returned." << std::endl; }

    std::string& _str1;
    std::string& _str2;
};

std::string foobar()
{
    std::string str1("Hello, World!");
    std::string str2("Goodbye, cruel World.");
    foo f(str1, str2);

    srand(time(NULL));

    return (rand() % 2) ? str1 : str2;
}

int …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

2
推荐指数
1
解决办法
192
查看次数

标签 统计

c++ ×4

c++11 ×4

return ×2

copy ×1

move ×1

move-semantics ×1