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) { /* ... */ }

2 つのアプローチ:

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プリミティブを格納するために使用する、または
  • autoHerb がプレゼンテーション (上記のリンク) で言及した、左から右への最新の C++ スタイルを維持するために、すべてに使用します。
4

1 に答える 1

2

C++98 では、std::string を const ref に格納しても問題ありませんでした。C++11 ではどうですか?

const 参照を一時的な文字列オブジェクトにバインドすることは、C++11 では問題ありません。以前と同じ動作をしています。

文字列の移動はコピーよりもはるかに安価であるため、一時的なものからのコピー初期化の理論上のコスト (これを回避することが const 参照を使用する利点です) は C++11 で大幅に削減されました。

コピー初期化の実際のコストは、コンパイラを最適化しても変更されていません。これは、コンパイラがコピー/移動を省略できるため、コストはかかりませんが、それが可能かどうかfind_pathは、実装方法によって異なります。


返された文字列のコピー/移動を絶対に避けたい場合で、コピーの省略を想定できない場合は、関数の外部でオブジェクトを作成し、参照によって関数に渡す必要があります。戻り値への参照をバインドするだけでは不十分です。

返された文字列のコピー/移動を避けたい場合、およびコピーの省略を想定できる場合は、通常のオブジェクトを使用することは const 参照と同じくらい適切です。

于 2016-07-27T12:15:39.387 に答える