フラグ-std=c++17
を使用してgcc-7.1でコンパイルすると、次のプログラムでエラーが発生します。
#include <string_view>
void foo(const char* cstr) {}
void bar(std::string_view str){
foo(str);
}
エラーメッセージは
In function 'void bar(std::string_view)':
error: cannot convert 'std::string_view {aka std::basic_string_view<char>}' to 'const char*' for argument '1' to 'void foo(const char*)'
foo(str);
他のライブラリ(abseil、bde)がconst char*
に暗黙的に変換する同様のstring_view
クラスを提供するため、const char*
への変換がないことに驚いています。
std::string_view
は、nullで終わる文字列を格納しないため、const char*
への変換を提供しません。基本的に、最初の要素へのポインタと文字列の長さを格納します。これは、const char*
を期待するfoo
(他にどのようにサイズを取得するのですか?)のような、ヌル終了文字列を期待する関数に渡すことができないことを意味します。価値がある。
ビューにnullで終わる文字列があることが確実にわかっている場合は、 std::string_view::data
を使用できます。
そうでない場合は、最初にstd::string_view
を使用することをお勧めします。保証されたヌル終了文字列std::string
が必要な場合は、これをお勧めします。ワンライナーの場合は、std::string(object).data()
を使用できます。
単にstd::string(string_view_object).c_str()
を実行して、保証されたヌル終了一時コピーを取得します(そして、行末でクリーンアップします)。
これは、文字列ビューがnull終了を保証しないために必要です。たとえば、長いバッファの真ん中を見ることができます。
このユースケースが高価であり、ボトルネックであることが証明されている場合は、nullで終了するかどうかを追跡する拡張string_view
を書くことができます(基本的に、生のchar const*
から構築された場合)。
次に、この拡張されたstring_view
を取得し、それをstd::string
にコピーするか、拡張されたstring_view
を直接保存し、適切にnullで終了したバッファーを返す暗黙的なcast-to -char const*
を保持するヘルパータイプを記述できます。
次に、string_view
の代わりにコードベースのどこでもその拡張ヘルパータイプを使用して、文字列ビューとstd文字列の相互作用を強化して、std文字列バッファの最後に行くビューがある場合をキャッチします。
しかし、実際にはおそらくそれはやり過ぎです。
おそらく、const char*
を使用するAPIをstring_view
に変更することをお勧めします。
foo(std::string(str).c_str())
を呼び出すことができます。