zrb*_*zrb 3 c++ const return-value move-semantics c++11
我有习惯(?!?!?)将所有内容作为"const"值返回.像这样...
struct s;
s const make_s();
s const &s0 = make_s();
s const s1 = make_s();
Run Code Online (Sandbox Code Playgroud)
使用移动操作和r值引用以及以下功能......
void take_s(s &&s0);
void take_s(s const &&s0); // Doesn't make sense
Run Code Online (Sandbox Code Playgroud)
我不能再写了......
take_s(make_s());
Run Code Online (Sandbox Code Playgroud)
我开始使用返回const值的约定的主要原因是为了防止有人编写这样的代码......
make_s().mutating_member_function();
Run Code Online (Sandbox Code Playgroud)
用例如下......
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, "; ")));
Run Code Online (Sandbox Code Playgroud)
看起来好像"返回const值"和r值引用不混合在这个特定的用例中.是对的吗?
**Edit 0: Extra question...**
Run Code Online (Sandbox Code Playgroud)
无论如何,该对象是临时的.为什么"const"会阻止移动?为什么我们不能移动"const"临时工?
jal*_*alf 11
你有两个相互冲突的目标.一方面,您希望阻止对返回的对象进行修改,但另一方面,您希望允许进行修改(这就是移动操作.它通过窃取其内部资源来修改源对象).
你需要下定决心.您希望对象是不可变的,还是希望人们能够修改它?
对于它的价值,我并不真正看到你通过首先返回const临时值而获得的收益.是的,你阻止人们调用变异成员函数,但你为什么要这样做?充其量,能够这样做是有用的,最坏的情况是,这是一个容易避免的错误.
而你正在做的事情并没有多大意义.暂时的全部意义在于它会在一瞬间消失,所以谁关心它是否会被修改?
rvalue引用和移动语义背后的整个想法是临时的,因此可以修改它们而不会伤害任何人.