【问题标题】:const auto& for storing functions results, is it worthwhile?const auto& 用于存储函数结果,值得吗?
【发布时间】:2016-12-01 09:53:05
【问题描述】:

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

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

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

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

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

在 C++98 中,将 std::string 存储在 const 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++ 风格(上面的链接)。

【问题讨论】:

  • 永不返回(取函数返回值)给临时对象作为参考。
  • @DieterLücking "C++ 故意指定将临时对象绑定到堆栈上对 const 的引用将临时对象的生命周期延长到引用本身的生命周期" herbsutter.com/2008/01/01/…
  • 相关/不完全是骗子:stackoverflow.com/questions/4986673/…
  • 我不确定您的问题参数是什么。怎么样……关于什么考虑?备择方案?与 C++98 相比? “告诉我一切”是在要求书中的一章......

标签: c++ c++11 auto const-reference


【解决方案1】:

在 C++98 中,将 std::string 存储在 const ref 是很好的。在 C++11 中的表现如何?

在 C++11 中将 const 引用绑定到临时字符串对象是可以的。它仍然具有与以前相同的行为。

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

复制初始化的实际成本并没有随着编译器的优化而改变,因为它们可能会忽略复制/移动,所以没有成本 - 尽管这是否可能,取决于find_path 的实现方式。


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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多