34

std::vector に C 配列としてアクセスする場合は、次の例でわかるように、少なくとも 4 つの異なる方法から選択できます。

#include <iostream>
#include <vector>

using namespace std;

int main() {
  std::vector<int> vec;
  vec.push_back(1);
  vec.push_back(2);
  vec.push_back(42);
  vec.push_back(24024);
  {
    int* arr = vec.data();
    cout << arr << endl; /* output: 0x9bca028 */
    cout << arr[3] << endl; /* output : 24024 */
  }
  {
    int* arr = &vec.front();
    cout << arr << endl; /* output: 0x9bca028 */
    cout << arr[3] << endl; /* output : 24024 */
  }
  {
    int* arr = &vec[0];
    cout << arr << endl; /* output: 0x9bca028 */
    cout << arr[3] << endl; /* output : 24024 */
  }
  {
    int* arr = &vec.at(0);
    cout << arr << endl; /* output: 0x9bca028 */
    cout << arr[3] << endl; /* output : 24024 */
  }
}

ほとんどの場合、私が見つけたのは&vec[0]. 私はそれが最もエレガントではないと思うので...なぜそれが最も使用されているのですか? より効率的ですか、それともより互換性がありますか? に関する多くのドキュメントが見つかりませんdata()

4

5 に答える 5

23

data()はC++11の新機能であるため、あまり頻繁に表示されません。使用するという考えは&vec.front()、おそらく私が(ほとんど決して)operator[]よりも頻繁に使用するために、私には思いもよらなかった。front()他の人も同じだと思います。

于 2012-05-24T15:05:53.107 に答える
21

C++11 を使用している場合は、使用することをお勧めしますdata()。特に、ベクトルが空の場合、他の 2 つのオプションのいずれかを使用すると、未定義の動作が発生します! C++11 を使用しておらず、ベクトルが空である可能性がある場合は、必ずその条件を確認してください。

于 2012-05-24T15:10:42.837 に答える
6

&vec[0] を使用するのが最も一般的ですが、私も同意しますが、少し奇妙に見えます。今後の為に、一つだけ注意しておきたいことがあります。ベクトルがたまたま operator&() をオーバーロードするクラスを持つオブジェクトのベクトルである場合、&vec[0] を呼び出すと奇妙な動作が発生することに注意してください。

これは、オブジェクトの内部連続配列の最初の項目の開始アドレスを取得しません。vec[0].operator&() が返すものは何でも返します。常にではないにしても、ほとんどの場合、それはあなたが探しているアドレスではありません (ジェダイの手の波)。

この良い例は、ATL の CComPtr です。operator&() をオーバーロードするため、ベクトルに格納すると問題が発生する可能性があります。これを回避するために、ATL には CComPtr で operator&() を非表示にするために使用できる CAdapt テンプレート クラスがあります。

于 2012-05-24T18:17:03.693 に答える
1

C++11 の前std::arraystd::vector、C スタイルの配列の代わりに使用される最も一般的なコンテナーでした。演算子は通常、[]一定時間のアクセスを意味するため (これstd::vectorがすべてです)、ほとんどのコーダーは通常、配列のようなアクセスと動作を反映するためにこのスタイルを選択します。

于 2012-05-24T15:11:23.003 に答える
1

data() はしばらくのstd::string間一部になっているので、それについて読んでください。std::vectordata() の実装が似ていることがわかりました。ときどき data() を使用して、astd::stringを raw バイトの配列として扱います。

于 2012-05-24T15:37:05.827 に答える