2016-03-05 28 views
0

移动赋值运算符的正确返回类型是什么?C++移动赋值运算符返回类型

const type& 

type& 

为什么? (我不认为我完全理解编译器如何确定l/r/x值。)

例如,考虑向量类的实现。

函数可能会返回一个向量。

vector myfunc() 
{ 
    vector v; 
    // add content to v 
    return v; 
} 

int main() 
{ 
    vector v2; 
    v2 = myfunc; 
} 

我们希望myfunc返回[?]过期值[?],即;我们希望调用移动赋值运算符,而不是复制赋值运算符。

拷贝赋值运算符可以是这样的:

const Vector& operator=(const Vector& vector) 
{ 
    if(this != &vector) 
    { 
     if(m_capacity_x != vector.m_capacity_x) 
     { 
      delete [] m_data; 
      m_data = new T[vector.m_capacity_x]; 
     } 

     m_size = vector.m_size_x; 
     m_capacity_x = vector.m_capacity_x; 

     std::copy(&(vector.m_data[0]), &(vector.m_data[vector.m_size_x - 1]), m_data); 
    } 

    return *this; 
} 

而此举赋值运算符可以是这样的:

Vector& operator=(Vector&& vector) 
{ 
    m_data = vector.m_data; 
    m_size = vector.m_size; 
    m_capacity = vector.m_capacity; 
    m_data = nullptr; 
    m_size = 0; 
    m_capacity = 0; 

    return *this; 
} 

不过是返回类型是否正确?应该是Vector&& [这是否存在?]或const Vector&

+3

您的“分配”操作员实际上都格式化硬盘驱动器。请返回*东西*。 – Fanael

+0

@Fanael err,格式化硬盘驱动器? – user3728501

+1

未定义返回非返回值时返回非'void'的函数结束时的行为。 – Fanael

回答

1

通常情况下,赋值运算符的返回类型为Vector&,但如果不想让人们做出时髦赋值链(((v1 = v2) = v3) = v4),则可以使用const Vector&。移动分配和复制分配都是“分配”。对于一个赋值运算符来说,返回类型不同于另一个赋值运算符是出人意料的,因此无论选择哪一个,都应该坚持。

这将是非常奇怪的返回Vector&&。仅仅因为你使用移动赋值操作符并不意味着你的对象是神奇的右值。你必须专门施放它,然后有可能意外退出该实例。

void some_function(Vector); 
Vector get_some_Vector(); 

Vector f; 
some_function(f = get_some_Vector()); //oops f is empty now 
+0

你的代码示例是做什么的? – user3728501

+0

@ user3728501我稍微改了一些例子,但基本上这是调用一个函数来获得一个新的'Vector'并将其赋值给'f',然后调用一个在'f'的新值上运行的函数。如果你从移动赋值中返回'Vector &&',在函数调用结束时,'f'可能是空的。 –

+0

我还是不明白。 'Vector &&'在这里如何解释? – user3728501

0

我个人不熟悉“移动赋值操作符”。我与一些不支持C++ 11的较老的编译器一起工作,但文档建议操作员应该只返回type&

http://en.cppreference.com/w/cpp/language/move_assignment

https://msdn.microsoft.com/en-us/library/dd293665.aspx

我只是做了针对C++搜索移动分配。

另外,在您的示例中,您没有从操作员返回任何内容。你应该返回一些东西,除非返回类型是无效的。

+0

是的,我会补充 – user3728501

3

我们可以问,赋值给右值有什么意义?分配通常在左值完成,所以这就是你应该返回的。另外,如果你的值最初是const,为什么它会支持赋值?否则,如果它不是const,为什么强制它?

因此,事情的正常过程是赋值操作符总是返回一个非const的左值。

+0

这是一个非常有见地的评论,谢谢。 – user3728501