1

文字列リテラルは配列オブジェクトです。

typeid("hello").name()   // char [6]

文字列リテラル(=配列)の大きさはコンパイル時に分かるので便利そうです。では、なぜstd::string配列への参照を取るコンストラクターがないのでしょうか?

// this would be great
template <int N>
std::string(const char (& array)[N]);

代わりにconst char * sconst char * s, size_t nまたは 2 つInputIteratorの s を取るコンストラクターがあります (例: const char * begin, const char * end)。これらにはすべて欠点があります。配列は暗黙的にポインターに変換され、サイズ情報が失われるため、さまざまな方法を使用してそれを取得します。動作しますが、ますますクレイジーな例:

// std::string(const char * s) version:
std::string s1("hello");                      // calls std::strlen(s) internally

// std::string(const char * s, size_t n) version:
std::string s2("hello", 5);                   // programmer does std::strlen(s) mentally
std::string s3("hello", sizeof("hello"));     // have to repeat string literal

// macro helper to avoid repeating string literal (ugly and dangerous)
#define STRLIT(x) std::string(x, sizeof(x));  // could be a function I guess
std::string s4 = STRLIT("hello");             // not much improvement (and macros are evil)

// std::string(InputIterator begin, InputIterator end) version:
char tmp[] = "hello";                         // copy array
std::string s5(&tmp[0], &tmp[sizeof(tmp)]);   // so you can reference it twice

// or trust the compiler to return the same address for both literals
std::string s6(&"hello"[0], &"hello"[sizeof("hello")]);   // totally crazy
4

3 に答える 3

2

このようなテンプレート化されたコンストラクターは、 の値ごとに個別にインスタンス化されますN。これにより、不要なコードが肥大化する可能性があります。

肥大化は避けられますが、この考えを、常に引用できるRaymond Chenからの回答と組み合わせましょう。

「なぜこの機能が存在しないのですか?」に対する答え。通常、「デフォルトでは機能は存在しません。誰かが実装する必要があります。」

于 2012-11-27T23:48:19.260 に答える
1

イテレータを使用する汎用コンストラクタがあるため:

std::string s7(std::begin(container), std::end(container));

注: std::begin/std::end には c++11 を想定していますが、同様のものを非常に簡単にすばやく作成できます。

于 2012-11-28T00:03:36.590 に答える
1

char const (&)[N](いくつかの静的に決定された ) を取るコンストラクターが必要かどうかを検討する際の重要な問題Nは、結果の内容がどうあるべきかstd::stringということです。それがどうあるべきかは明らかかもしれませんが、そうではないと思います。これを考慮してくださいstd::string("abc\0def")

  1. 2 つの null バイトを含む 8 つの要素を持つ文字列である可能性があります。
  2. 2 番目の null バイトを除いて、7 つの要素を持つ文字列である可能性があります。
  3. 最初の null バイトから始まるすべてを除いて、3 つの要素を持つ文字列である可能性があります。

使用する場合

std::cout << "string='" << "abc\0def" << "'\n";

3 番目のオプションが表示されます。どうやら、これが唯一の健全な代替手段のようです...

于 2012-11-28T00:04:00.583 に答える