web-dev-qa-db-ja.com

空のstd :: stringのインデックス0に依存するのは悪いことですか?

std::string my_string = "";
char test = my_string[0];

これはクラッシュしないことに気づきました。テストするたびに、テストは0になります。

常に0であることに依存できますか?それとも恣意的ですか?

これは悪いプログラミングですか?

編集:いくつかのコメントから、私はこれの有用性についていくつかの誤解があることを収集します。

これの目的は、文字列が空かどうかを確認することではありません。文字列が空かどうかを確認する必要はありません。

状況は、空である場合とそうでない場合がある文字列がある場合です。この文字列の最初の文字だけが気になります(空でない場合)。

文字列が空かどうかを確認してから、空でない場合は最初の文字を確認する方が効率が悪いように思われます。

if (! my_string.empty())
    test = my_string[0];
else
    test = 0;

代わりに、文字列が空かどうかを確認する必要なしに、最初の文字を見ることができます。

test = my_string[0];
46
beauxq

C++ 14

いいえ;あなたはそれに頼ることができます。

21.4.5.2(または[string.access])には、次のものがあります。

戻り値:*(begin() + pos) if pos < size()。それ以外の場合は、値charT()のタイプcharTのオブジェクトへの参照を返します。オブジェクトを変更すると、未定義の動作が発生します。

言い換えると、pos == size()(両方が0の場合に真)の場合、演算子はデフォルトで構築された文字タイプ禁止されている)への参照を返します。変更する

空の(または0サイズの)文字列の場合は特別な場合ではなく、すべての長さで同じように機能します。


C++ 03

そして最も確実にC++ 98も同様です。

状況によります。

これが21.3.4.1公式ISO/IEC14882からです。

戻り値:pos < size()の場合、data()[pos]を返します。それ以外の場合、pos == size()の場合、constバージョンはcharT()を返します。それ以外の場合、動作は定義されていません。

68

@Bartek Banachewiczの answer は、どのような状況であなたが仮定を立てることができるかを説明しています。それを付け加えたい

これは悪いプログラミングです。

どうして?いくつかの理由で:

  1. これがバグではないことを確認するためだけに、言語弁護士である必要があります。このページがなければ答えはわかりませんが、率直に言って、あなたもわざわざ知る必要はないと思います。
  2. 文字列がヌル文字で終了する文字列であるという直感がない人は、標準を読むか、友達に尋ねるまで、あなたが何をしようとしているのかわかりません。
  3. 驚き最小の原則 を悪い方法で破ります。
  4. 「あなたが意味することを書く」という原則に反します。つまり、コードに問題領域の概念を表現させることです。
  5. マジックナンバー の使用の並べ替え(この場合、0が実際にマジックナンバーを構成するかどうかは議論の余地があります)。

続けましょうか。 ...私はあなたがほとんどすべての点で優れた代替案を持っているとほぼ確信しています。私はあなたがこれをやりたいと思うように自分自身を操作するために「悪い」何かをしたと推測することさえします。

常に覚えておいてください:あなたに相談しない他の人々は、遅かれ早かれこのコードを維持する必要があります。考えてみてください。あなた自身、それを理解できる人。さらに、今から10年後に、自分のトリックを覚えていると誰が言いますか?あなたはその混乱したメンテナかもしれません...

31
einpoklum