移动语义和返回常量值

我有将所有内容作为const"值返回的习惯(?!?!?).像这样……

I have the habit (?!?!?) of returning everything as a "const" value. Like this...

struct s;

s const make_s();

s const &s0 = make_s();
s const s1 = make_s();

具有移动操作和右值引用以及以下功能...

With move operations and r-value references and the following functions...

void take_s(s &&s0);
void take_s(s const &&s0);  //  Doesn't make sense

我写不下去了……

take_s(make_s());

我开始使用返回 const 值的约定的主要原因是为了防止有人编写这样的代码...

The main reason I started using the convention of returning const values is to prevent someone from writing code like this...

make_s().mutating_member_function();

用例如下...

struct c_str_proxy {
    std::string m_s;

    c_str_proxy(std::string &&s) : m_s(std::move(s)) {
    }
};

c_str_proxy c_str(std::string &&s) {
    return c_str_proxy(s);
}

char const * const c_str(std::string const &s) {
    return s.c_str();
}

std::vector < std::string > const &v = make_v();
std::puts(c_str(boost::join(v, ", ")));

std::string const my_join(std::vector < std::string > const &v, char const *sep);

//  THE FOLLOWING WORKS, BUT I THINK THAT IS ACCIDENTAL
//  IT CALLS
//
//      c_str(std::string const &);
//
//  BUT I THINK THE TEMPORARY RETURNED BY
//
//      my_join(v, "; ")
//
//  IS NO LONGER ALIVE BY THE TIME WE ARE INSIDE
//
//      std::puts
//
//  AS WE ARE TAKING THE "c_str()" OF A TEMPORARY "std::string"
//
std::puts(c_str(my_join(v, "; ")));

看起来好像返回 const 值"和 r 值引用不会在这个特定用例中混合使用.对吗?

Looks as if "returning const value" and r-value references don't mix in this particular use case. Is that right?

**Edit 0: Extra question...**

无论如何,该对象是临时的.为什么const"应该阻止移动?为什么我们不能移动const"临时对象?

The object is temporary anyway. Why should "const" prevent moving? Why can't we move "const" temporaries?

推荐答案

你有两个相互冲突的目标.一方面,您希望防止对返回的对象进行修改,但另一方面,您希望允许进行修改(这就是一个动作操作是.它通过窃取其内部资源来修改源对象.

You have two conflicting goals. On one hand, you want to prevent modifications from being made to the returned object, but on the other hand, you want to allow modifications to be made (that's what a move operation is. It modifies the source object, by stealing its internal resources).

你需要下定决心.您希望对象是不可变的,还是希望人们能够修改它?

You need to make up your mind. Do you want the object to be immutable, or do you want people to be able to modify it?

对于它的价值,我真的不知道首先返回 const 临时变量会获得什么.是的,您阻止人们对其调用变异成员函数,但是为什么要这样做?最好的情况是,能够这样做是有用的,最坏的情况是,这是一个很容易避免的错误.

For what it's worth, I don't really see what you'd gain by returning const temporaries in the first place. Yes, you prevent people from calling a mutating member function on it, but why would you want to? At best, being able to do so can be useful, and at worst, it's a mistake that is easily avoided.

而你所做的并没有多大意义.临时的全部意义在于它马上就会消失,所以谁在乎它是否被修改?

And what you're doing doesn't really make much sense. The entire point in a temporary is that it's going to go away in a moment, so who cares if it gets modified?

右值引用和移动语义背后的整个想法是临时对象是临时的,因此可以在不伤害任何人的情况下对其进行修改.

The entire idea behind rvalue references and move semantics is that temporaries are temporary, and so they can be modified without harming anyone.

相关文章