8

C++14/C++1y (n3690) の草案にざっと目を通していると、セクション §21.7 でbasic_stringリテラル接尾辞が導入されていることに気付きました。

inline namespace literals {
inline namespace string_literals {
  // 21.7, suffix for basic_string literals:
  string operator "" s(const char *str, size_t len);
  u16string operator "" s(const char16_t *str, size_t len);
  u32string operator "" s(const char32_t *str, size_t len);
  wstring operator "" s(const wchar_t *str, size_t len);
}
}

私の質問は次のとおりです。

  • basic_stringリテラルを使用すると、実行時に高速になる可能性はありますか?
  • 私の「素朴な」実装は完全に間違っていますか?
  • ROM 内のデータのレイアウトは、basic_stringリテラルで異なる可能性がありますか、またはコンパイル時と実行時のその他の違いはありますか?

バックグラウンド

これにより、次のような文字列リテラルを直接使用できることがわかっています。

std::string s1 = "A fabulous string"s;

void sfunc(std::string arg);

int main() {
    sfunc("argument"s);
}

しかし、変換コンストラクター に依存することの利点は何string(const char*)ですか?

「古い」コードは次のようになります。

std::string s1 = "A fabulous string";  // c'tor string(const char*)

void sfunc(std::string arg);

int main() {
    sfunc("argument");   // auto-conversion via same c'tor
}

私が見る限り、の実装operator "" s()は基本的に次のようになります。

std::string operator "" s(const char* lit, size_t sz) {
    return std::string(lit, sz);
}

つまり、同じc'torを使用するだけです。そして私の推測では、それは実行時に行われなければならないということですが、私は間違っていますか?

編集:Nicol Bolasが私の例の下で正しく指摘したように、同じコンストラクターを使用していません、追加の長さを持つコンストラクターを使用しています。これは明らかに、構築に非常に役立ちます。これは私に疑問を残します: これは、コンパイラが文字列リテラルを ROM に入れること、またはコンパイル時に同様のものを入れることよりも良いですか?

4

3 に答える 3

5

つまり、同じc'torを使用するだけです。

OK、それがどのように見えるか見てみましょう:

string fromLit = "A fabulous string"s;
string fromBare = string("A fabulous string");

に欠けているものがありfromBareますか? あなたのためにそれを綴らせてください:

string fromBare = string("A fabulous string"/*, NOTHING*/);

ええ、文字列の長さを取得せずに文字列の長さを取得することはできません... 長さを取得します。つまりfromBare、文字を見つけるためにリテラルを反復処理する必要があります\0。実行時。fromLitしない; コンパイラは、文字列の長さをコンパイル時に決定されるパラメーターとして提供します。使用する価値のあるコンパイラは、長さを実行可能コードに焼き付けるだけです。

たとえそうでなかったとしても、他の理由でそれはより良いことです. このことを考慮:

void SomeFunc(const std::string &);
void SomeFunc(const char *);

SomeFunc("Literal");
SomeFunc("Literal"s);
SomeFunc(std::string("Literal"));

最後の 2 つは同じことを行いますが (前に指摘した点を除いて)、そのうちの 1 つははるかに短くなっています。あなたがusing std::string(または愚かusing namespace std;に)採用したとしても、2番目のものはまだ短い. それでも、何が起こっているのかは明確です。

于 2013-08-26T08:35:49.597 に答える
1

これにより、コンパイル時の安全性が向上します。

nullが埋め込まれた std::string をどのように作成しますか?

null 文字を含む文字列リテラルから aを作成する唯一の方法std::stringは、文字列リテラルのサイズを指定する (エラーが発生しやすい) か、initializer_list構文を使用する (冗長) か、複数の呼び出しで何らかのループを実行するpush_back(さらに冗長) ことです。 )。ただし、リテラル コンストラクターを使用すると、サイズが自動的に渡されるため、エラーの原因となる可能性がなくなります。

于 2013-10-04T00:27:21.430 に答える