C++ 如何在没有std::move的情况下移动临时对象

C++ 如何在没有std::move的情况下移动临时对象,c++,c++11,move-semantics,copy-elision,C++,C++11,Move Semantics,Copy Elision,类的Move构造函数接受可以引用临时对象的右值引用。所以,我有临时对象和适当的move构造函数,它们可以接受对临时对象的引用,但move构造函数不被调用。 怎么了 //g++ 5.4.0 #include <iostream> class foo { int data; public: foo(int v) : data(v) {std::cout << "foo(int)\n";} foo(foo&& f)

类的Move构造函数接受可以引用临时对象的右值引用。所以,我有临时对象和适当的move构造函数,它们可以接受对临时对象的引用,但move构造函数不被调用。 怎么了

    //g++  5.4.0

#include <iostream>

class foo
{
    int data;
public:
    foo(int v) : data(v) {std::cout << "foo(int)\n";}

    foo(foo&& f)
    {
        std::cout << "moved\n";
    }

    void print()
    {
        std::cout << data;
    }
};

void acceptTmp(foo f)
{
    f.print();
}

int main()
{
    foo f1 = foo(100);
    f1.print();
    acceptTmp(foo(200)); //also does not move
}
//g++5.4.0
#包括
福班
{
int数据;
公众:
foo(intv):数据(v){std::cout
怎么了

    //g++  5.4.0

#include <iostream>

class foo
{
    int data;
public:
    foo(int v) : data(v) {std::cout << "foo(int)\n";}

    foo(foo&& f)
    {
        std::cout << "moved\n";
    }

    void print()
    {
        std::cout << data;
    }
};

void acceptTmp(foo f)
{
    f.print();
}

int main()
{
    foo f1 = foo(100);
    f1.print();
    acceptTmp(foo(200)); //also does not move
}
没有什么不对的,只是您希望调用move构造函数

在C++17之前,从抽象机器的角度来看,临时对象确实会被移动到参数中。但是,该标准允许编译器通过直接构造临时对象来代替它将被移动到的对象来省略移动。你不能依赖移动构造函数t的副作用o发生

在C++17之后,没有涉及临时对象或移动。标准保证参数构造到位



缺少移动是一件好事。移动对象可能比不移动对象慢。

通常编译器通过应用对代码执行优化和转换。复制/移动省略是“仿佛”的唯一例外即使有副作用,编译器也会优化复制和移动操作,因为复制和移动操作是有代价的

当然,在C++17之前,这取决于编译器,可能还取决于优化级别。但从C++17开始,可以保证省略

如果要指示编译器不执行省略,可以使用
-fno elide构造函数
编译器标志

请参阅以下链接以了解有关复制/移动ellison的更多信息:


请看@songyuanyao,我知道c++11没有保证的复制省略,但这种行为发生在c++11之前,c++17没有保证,但它是允许的。事实上,大多数体面的编译器都会应用这种优化。@AlexF不,移动赋值也不称为复制初始化“如果T是类类型,而另一个类型的cv非限定版本是T或从T派生的类,则会检查T的非显式构造函数,并通过重载解析选择最佳匹配。然后调用构造函数初始化对象。”请参阅:没有(N)示例代码中的RVO。当函数按值返回时,返回值优化是一种特殊的复制省略。示例中没有函数按值返回
foo
。@user207933--对不起,那么我误解了这个问题。我将编辑我的答案。谢谢你指出。我的答案现在可以了吗?我觉得可以了。