Const Auto&用于存储函数结果,值得吗?

const auto& for storing functions results, is it worthwhile?

本文关键字:值得 结果 函数 Auto 用于 存储 Const      更新时间:2023-10-16

假设我们有一个函数,它返回一个类似std::string:的复杂对象

std::string find_path(const std::string& filename);

是否值得将调用该方法的结果存储在const auto&中?

void do_sth() {
   //...
   const auto& path = find_path(filename);
   //...
} 

这种方法可以防止复制/移动对象。所以这很好。但另一方面,引入了auto来统一赋值的左侧。Herb Sutter在2014年CppCon2的演讲中提到了C++从左到右的现代风格https://www.youtube.com/watch?v=xnqTKD8uD64(39:00-45:00)。

在C++98中,将std::string存储在常量ref是可以的。它在C++11中怎么样?

更新(2016-07-27 2:10 GMT+0):

对不起,我的问题不准确。我指的是编码风格——是添加const &更好,还是只使用auto,让编译器随心所欲。

更新示例:

unsigned int getTimout() { /* ... */ }
int getDepth() { /* ... */ }
std::string find_path(const std::string& filename,
                      unsigned int timeout,
                      int depth) { /* ... */ } 
void open(const std::string& path) { /* ... */ }

两种方法:

void do_sth() {
   //...
   auto timeout = getTimeout();
   auto depth = getDepth();
   const auto& path = find_path(filename, timeout, depth);
   open(path)
   //...
} 

void do_sth() {
   //...
   auto timeout = getTimeout();
   auto depth = getDepth();
   auto path = find_path(filename, timeout, depth);
   open(path);
   //...
}

问题是:我们是否应该

  • 使用const auto&存储复杂返回对象,使用auto存储基元,或者
  • 使用auto来保持Herb在他的演示中提到的从左到右的现代C++风格(上面的链接)

在C++98中,将std::字符串存储在const ref中是可以的。它在C++11中怎么样?

在C++11中,将const引用绑定到临时字符串对象是可以的。它的行为仍然和以前一样。

在C++11中,从临时复制初始化的理论成本(避免这种情况是使用常量引用的优点)已经大大降低,因为移动字符串比复制便宜得多。

复制初始化的实际成本并没有随着编译器的优化而改变,因为它们无论如何都可能消除复制/移动,所以没有成本——尽管这是否可能取决于find_path的实现方式。


如果您绝对希望避免复制/移动返回的字符串,并且不能假设复制省略,那么您必须在函数外部创建对象,并通过引用将其传递给函数。仅将引用绑定到返回值是不够的。

如果您想避免复制/移动返回的字符串,并且可以假设复制省略,那么使用正则对象和const引用一样好。