C++0x : when a temporary object equals another temporary object

标签 c++ c++11 rvalue-reference move-semantics

struct F
{
private:
    int* data;

public:
    F( int n ) 
    { 
        data = new int; 
        *data = n; 
    }

    F( int* p ) 
    { 
        data = p; 
    }

    F& operator=( const F& f ) 
    { 
        *data = *(f.get_data()); 
        return *this; 
    }

    F& operator=( F&& f ) 
    {
        delete data;
        data = f.data;
        f.data = nullptr;
        return *this;
    }

    F& operator=( int n ) { *data = n; return *this; }

    F operator()() 
    {
        F cpy_f( data );
        return std::move( cpy_f );
    }

    int* get_data() const { return data; }
};

int main()
{
    F f( 12 );
    F g( 14 );
    f() = g();
    cout << *(f.get_data()) << endl;
}

在这个例子中,f()g()分别返回一个临时对象,所以f()=g()结果在 temporary object equal to temporary object 的表达式中。如果值被正确复制,我会期望答案是 14。但是,它不是调用复制赋值但是调用 move 赋值!结果,答案不是 14。

这让我很困惑。虽然从 f()g() 返回的对象是临时的,但它们与其他一些对象共享一些信息。这意味着临时对象可能很快就会为共享信息做一些工作。所以我认为语义调用复制赋值是正确的行为。

附言。我的编译器是 g++4.7 20110430

最佳答案

你的 operator()返回一个值,而不是引用或指针。因此,它返回一个临时的。临时对象隐式优先绑定(bind)到&&(它们是唯一这样做的类型)。因此,如果有 move 赋值运算符供他们使用,他们会更愿意使用它。

你的问题是当你在你的 operator() 中这样做时你停止了合理的事情功能:

F cpy_f( data );

F 的构造函数接受指针的函数使用指针值本身,有效地采用了指针。在那一刻,你现在有两个 F指向相同数据的实例。

如果这是你想要的合理的东西,那么你不能让你的 move 赋值运算符删除指针。您需要调和您可以拥有两个 F 的事实指向同一事物的实例。两者需要共享指针的所有权。那么...您打算如何做到这一点?

我建议完全摆脱这个构造函数。它只会给你制造更多的问题。我还建议使用 std::unique_ptr<int> data;而不是裸指针。这样,您就不必编写 move 构造函数/赋值运算符(尽管您确实需要复制构造函数/赋值运算符)。

关于C++0x : when a temporary object equals another temporary object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9107446/

相关文章:

c++ - 在 CMake 中混合 C 和 C++,什么是 CMakeCCompilerId.c 以及如何丢弃它

c++ - 使用 pthread_cond_wait 等待的线程在收到信号后需要多长时间才能唤醒?我如何估计这个时间?

c++ - autoexp.dat 不解析 union ?

c++ - 使用代理对象延迟更新与 "Avoid unnamed objects with custom construction and destruction"

c++ - Clang 和 GCC 在使用大括号表示法和 initializer_list 时不同意构造函数的选择

c++ - FastDelegate 的 Variadic 版本和额外的值拷贝

c++ - 如何使一个类能够调用其他类函数的数组?

c++ - 任意但编译时已知数量的类型的元组

c++ - 生命周期延长和条件运算符

c++ - 是否可以实现 std::move-and-clear 函数?