4

假设我们有一个返回复杂对象的函数,例如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::stringat 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++ 风格(上面的链接)。
4

1 回答 1

2

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

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

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

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


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

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

于 2016-07-27T12:15:39.387 回答