std::string
からへの暗黙的な変換がありstd::string_view
、プログラマーがこれを行えば多くのぶら下がり参照が発生する可能性があるにもかかわらず、安全ではないとは考えられません。気を付けていない。
一方、同じ引数を使用して完全に逆の方法でstd::string_view
からへの暗黙的な変換はありません。std::string
プログラマーが注意を払わないかもしれないので。
C++ に生のポインターの代替手段があるのは素晴らしいことですがconst char*
、生のポインターは非常にわかりにくく、骨まで削ぎ落とされています。
- 暗黙的
const char*
->std::string
:わかりました - 暗黙的
std::string_view
->std::string
:いいえ - 割り当て
std::string
=const char*
:わかりました - 割り当て
std::string
=std::string_view
:わかりました std::string
+= の追加const char*
:わかりましたstd::string
+= の追加std::string_view
:わかりました- 連結
const char*
+std::string
:わかりました - 連結
std::string_view
+std::string
:いいえ - 連結
std::string
+const char*
:わかりました - 連結
std::string
+std::string_view
:いいえ
何か見逃しているのでしょうか、それともこれはまったくのナンセンスなのでしょうか?
結局のところ、この文字列ビューは、に似ている重要な要素をすべて備えていないとどれほど役に立つのでしょうかconst char*
?これをのエコシステムに統合する意味は何でしょうか?標準ライブラリそれを完成させるための最後のステップを踏んでいないのに、文字列の一部を表すオブジェクトが必要な場合は、独自のオブジェクトを作成できます。実際、多くのライブラリが何年も前にすでにそれを行っています。何かを標準化する主な目的は、最も幅広いユースケースに役立つようにすることです。そうではありませんか?
彼らはこれを修正するつもりですか?C++23?
ベストアンサー1
問題は、std::string_view
->std::string
がコピー暗黙の -> はヒープ割り当てを含む基礎メモリを完全にコピーしますが、暗黙のstd::string
-> はstd::string_view
そうではありません。そもそも a を使用する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
オブジェクトを何度も作成します。これについてコンパイラに通知してもらいたいと思うでしょう。