私たちのチームは10年以上前のC++コードベースで作業しており、最近C++ 17コンパイラに切り替えました。そこで、コードを最新化する方法を探しています。 YouTubeでのカンファレンストークで、const char*
グローバル文字列をconstexpr string_view
に置き換えるという提案を聞きました。
このようなconst char*
グローバル文字列定数がコードに多数含まれているので、知っておく必要のある問題や潜在的な問題があるかどうかを確認したいと思いますか?
これらの問題は、認識しておく価値があります。
std::string_view
は、null
で終了する必要はありません。したがって、一部のconst char*
をstring_view
で置き換え、以前にnull
で終了したchar*
サブストリングの構築をstring_view
を介してstd::string_view::substr
で置き換える場合、null
で終了する文字列を必要とするAPIに基本となるポインタを渡すことはできません。例(UBなしですが、これも簡単に構築できます):
void legacy(const char *str) {
std::printf("%s\n", str);
}
constexpr std::string_view sv1 = "abcde";
constexpr std::string_view sv2 = sv1.substr(0, 2); // view on "ab"
legacy(sv2.data()); // Not intended: prints "abcde"
std::string
からconst char*
を暗黙的に構築することはできますが、std::string_view
を使用してそれを行うことはできません。これは、ディープコピーが内部で行われるべきではなく、明示的に要求された場合にのみ行われるという考え方です。例:
std::map<std::string, int> m;
constexpr std::string_view sv = "somekey";
constexpr const char *old = "somekey";
m[old] = 42; // works as expected
m[sv] = 42; // fails to compile
m[std::string(sv)] = 42; // be explicit, this is ok
プロジェクトでのグローバルconst char*
インスタンスの既存の使用方法によっては、この動作をさまざまな場所で手動で行う必要がある場合があります。