あなたが「Almost Always Auto」グループの一員である場合、UDL は非常に重要です。これを行うことができます:
auto str = "Foo"s;
したがって、はではなく、str
本物のになります。したがって、いつ何をするかを決めることができます。std::string
const char*
これは、戻り型の自動推論にも重要です。
[]() {return "Foo"s;}
または、実際には型推論の任意の形式:
template<typename T>
void foo(T &&t) {...}
foo("Foo"s);
[...] の代わりに [...] を使用する唯一の利点は、最初のケースでコンパイラーがコピー省略を実行できることです (私が思うに)。これは、2 番目のケースでのコンストラクター呼び出しよりも高速です。
コピー省略は、コンストラクター呼び出しよりも高速ではありません。いずれにせよ、オブジェクトのコンストラクターの 1 つを呼び出しています。問題はどちらかです:
std::string str = "foo";
これにより、コンストラクターへの呼び出しがstd::string
発生しますconst char*
。ただしstd::string
、文字列を独自のストレージにコピーする必要があるため、文字列の長さを取得する必要があります。そして、長さがわからないため、このコンストラクターは長さstrlen
を取得するために使用する必要があります (技術的にはchar_traits<char>::length
、しかし、おそらくそれほど速くはなりません)。
対照的に:
std::string str = "foo"s;
これは、次のプロトタイプを持つ UDL テンプレートを使用します。
string operator "" s(const char* str, size_t len);
ほら、コンパイラは文字列リテラルの長さを知っています。そのため、UDL コードには文字列へのポインタとサイズが渡されます。したがって、 aおよびastd::string
を取るコンストラクターを呼び出すことができます。したがって、文字列の長さを計算する必要はありません。const char*
size_t
問題のアドバイスは、リテラルのすべてs
の使用をバージョンに変換することではありません。s の配列の制限に問題がなければchar
、それを使用してください。アドバイスは、そのリテラルを a に保存する場合はstd::string
、それがまだリテラルであり、漠然としたものではない間にそれを行うのが最善であるということconst char*
です。