使用 return (std::stringstream ss).str() 的编译器优化
Compiler Optimization with return (std::stringstream ss).str()
以下函数接受一个字符串作为参数,returns 另一个,经过一些处理后。
假设编译器将执行移动优化并且我不会在每次调用后都复制字符串的内容是否足够公平?这个函数应该遵循 copy elision [(N)RVO]?
这种做法是否明智?
std::string foo(std::string const& s)
{ // Perform sanity check on s
// ...
std::stringstream ss;
// do something and store in ss
// ...
return ss.str();
}
因为,除此之外,我一般都遵循按引用返回字符串的做法。所以,也就是说,我的函数签名应该是:
void foo (std::string const& inValue, std::string& outValue);
ss.str()
将创建一个临时字符串。如果您将该字符串分配给一个新实例,例如
std::string bar = foo("something");
复制省略或移动语义将开始。
现在,如果您已经创建了一个字符串并将其分配给 foo
的 return,那么移动分配将开始
std::string bar;
// do stuff
bar = foo("something");
我更喜欢这种方法,因为它不需要您在其中创建一个对象
void foo (std::string const& inValue, std::string& outValue);
你会创建一个空字符串只是为了将它传递给函数来填充吗?这意味着你有一个构造和一个赋值,在第一个例子中你可以只有一个构造。
根据 this 当您 return 值时更优化:
the Return Value Optimization (RVO), allows the compiler to optimize away the copy by having the caller and the callee use the same chunk of memory for both “copies”.
以下函数接受一个字符串作为参数,returns 另一个,经过一些处理后。
假设编译器将执行移动优化并且我不会在每次调用后都复制字符串的内容是否足够公平?这个函数应该遵循 copy elision [(N)RVO]?
这种做法是否明智?
std::string foo(std::string const& s)
{ // Perform sanity check on s
// ...
std::stringstream ss;
// do something and store in ss
// ...
return ss.str();
}
因为,除此之外,我一般都遵循按引用返回字符串的做法。所以,也就是说,我的函数签名应该是:
void foo (std::string const& inValue, std::string& outValue);
ss.str()
将创建一个临时字符串。如果您将该字符串分配给一个新实例,例如
std::string bar = foo("something");
复制省略或移动语义将开始。
现在,如果您已经创建了一个字符串并将其分配给 foo
的 return,那么移动分配将开始
std::string bar;
// do stuff
bar = foo("something");
我更喜欢这种方法,因为它不需要您在其中创建一个对象
void foo (std::string const& inValue, std::string& outValue);
你会创建一个空字符串只是为了将它传递给函数来填充吗?这意味着你有一个构造和一个赋值,在第一个例子中你可以只有一个构造。
根据 this 当您 return 值时更优化:
the Return Value Optimization (RVO), allows the compiler to optimize away the copy by having the caller and the callee use the same chunk of memory for both “copies”.