真剣に、何が起きていない。 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で修正するつもりですか?
問題は、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...
}
関数foo2
はconst std::string&
パラメーターを使用できましたが、std::string_view
を使用したため、std::string
ではないストリングを渡すとより効率的です。驚きはありません。ただし、const std::string&
パラメーターを指定した場合よりも効率が低下します。
foo2
がstd::string
引数で呼び出された場合(例:foo1
):foo2
がfoo3
を呼び出すと、文字列のコピーが作成されます。 const std::string&
引数がある場合、すでに持っているオブジェクトを使用できた可能性があります。foo2
引数を指定してconst char*
を呼び出す場合:std::string
コピーは遅かれ早かれ作成する必要があります。 const std::string&
パラメータを使用すると、以前に作成されますが、全体的にはどちらの方法でも1つのコピーしかありません。foo2
がfoo3
のような複数の関数を呼び出すか、ループでfoo3
を呼び出すと想像してください。まったく同じstd::string
オブジェクトを何度も作成しています。コンパイラーにこれについて通知してほしいと思うでしょう。