web-dev-qa-db-ja.com

std :: string_viewからstd :: stringへの変換は暗黙的です。地獄は何を考えましたか?

真剣に、何が起きていない。 std::stringからstd::string_viewへの暗黙的な変換があり、安全ではないと見なされません。たとえプログラマーが注意を払わなければ、これは確かに多くのぶら下がり参照を引き起こすかもしれませんが。

一方、彼らは、std::string_viewからstd::stringへの暗黙的な変換を、同じ引数を使用して完全に反対の方法で却下しました:プログラマーは注意しないかもしれません.

彼らが生のconst char*ポインターの置き換えを作成し、それを非常に混乱させて骨に落としているのは素晴らしいことです:

  • 暗黙のconst char*-> std::string[〜#〜] ok [〜#〜]
  • 暗黙のstd::string_view-> std::string[〜#〜] nope [〜#〜]
  • 割り当てstd::string = const char*[〜#〜] ok [〜#〜]
  • 割り当てstd::string = std::string_view[〜#〜] ok [〜#〜]
  • 末尾にstd::string + = const char*[〜#〜] ok [〜#〜]
  • std::string + = std::string_viewの追加:[〜#〜] ok [〜#〜]
  • 連結const char* + std::string[〜#〜] ok [〜#〜]
  • 連結std::string_view + std::string[〜#〜] nope [〜#〜]
  • 連結std::string + const char*[〜#〜] ok [〜#〜]
  • 連結std::string + std::string_view[〜#〜] nope [〜#〜]

私は何かを見逃していますか、これはまったくナンセンスですか?

最後に、この文字列ビューは、const char*に似た重要な要素をすべて含まないので、どれほど便利ですか?それを完成させる最後のステップを作らずに、stdlibのエコシステムに統合することのポイントは何ですか?結局のところ、文字列の一部を表すオブジェクトだけが必要な場合は、独自に作成できます。実際、何年も前に、多くのライブラリがすでにそうでした。何か標準を作ることの全体的なポイントは、それを最も広い範囲のユースケースに役立つようにすることですよね?

彼らはこれをC++ 2aで修正するつもりですか?

14
GreenScape

問題は、std::string_view-> std::stringが、基礎となるメモリのコピーを作成し、ヒープの割り当てを完了するのに対し、暗黙的なstd::string-> std::string_view ではない。そもそもstd::string_viewを使用するのが面倒な場合は、明らかにコピーに関心があるので、暗黙のうちにコピーが発生することは望ましくありません。

この例を考えてみましょう:

void foo1(const std::string& x)
{
    foo2(x);
}
void foo2(std::string_view x)
{
    foo3(x);
}
void foo3(const std::string& x)
{
    // Use x...
}

関数foo2const std::string&パラメーターを使用できましたが、std::string_viewを使用したため、std::stringではないストリングを渡すとより効率的です。驚きはありません。ただし、const std::string&パラメーターを指定した場合よりも効率が低下します。

  • foo2std::string引数で呼び出された場合(例:foo1):foo2foo3を呼び出すと、文字列のコピーが作成されます。 const std::string&引数がある場合、すでに持っているオブジェクトを使用できた可能性があります。
  • foo2引数を指定してconst char*を呼び出す場合:std::stringコピーは遅かれ早かれ作成する必要があります。 const std::string&パラメータを使用すると、以前に作成されますが、全体的にはどちらの方法でも1つのコピーしかありません。

foo2foo3のような複数の関数を呼び出すか、ループでfoo3を呼び出すと想像してください。まったく同じstd::stringオブジェクトを何度も作成しています。コンパイラーにこれについて通知してほしいと思うでしょう。

5
Arthur Tacca