yohhoyの日記

技術的メモをしていきたい日記

dataメンバ関数と戻り値ポインタ型のconst性

C++標準ライブラリ提供のシーケンスコンテナ/文字列クラスdataメンバ関数 についてメモ。

まとめ:

  • std::basic_string<E>::dataメンバ関数は、常に文字列先頭を指すconst E *を返す。この仕様はC++98/03からC++11まで不変。*1
  • C++11で追加されたstd::vector<T>::data, std::array<T>::dataメンバ関数は、対象オブジェクトのconst性に応じて先頭要素を指すT *もしくはconst T *を返す。同メンバ関数C++03以前では提供されない。
対象オブジェクトの型 C++03以前 C++11 C++17
basic_string<E> const E * const E * E *
const basic_string<E> const E * const E * const E *
vector<T> (N/A) T * T *
const vector<T> (N/A) const T * const T *
array<T> (N/A) T * T *
const array<T> (N/A) const T * const T *

C++03

ISO C++03 21.3よりbasic_stringクラステンプレートおよび関連するメンバ関数の宣言を引用(一部は簡略化)。vectorクラステンプレートにはdataメンバ関数は存在せず、またarrayクラステンプレートは提供されない。

namespace std {
  template<class E>
  class basic_string {
    public:
    //...
    // 21.3.6 string operations:
    const E * c_str() const;
    const E * data() const;
    //...
  };
}

C++11

C++11(N3337) 21.4, 23.3.2.1, 23.3.6.1よりクラステンプレートおよび関連するメンバ関数の宣言を引用(一部は簡略化)。

namespace std {
  template<class E>
  class basic_string {
    public:
    //...
    // 21.4.7, string operations:
    const E * c_str() const noexcept;
    const E * data() const noexcept;
    //...
  };
}
namespace std {
  template <class T, size_t N>
  struct array {
    //...
    T * data() noexcept;
    const T * data() const noexcept;
  };
}
namespace std {
  template <class T>
  class vector {
  public:
    //...
    // 23.3.6.4, data access
    T * data() noexcept;
    const T * data() const noexcept;
    //...
  };
}

関連URL

*1:余談:“C++11から vector::data で内部バッファにWriteアクセスできる” と “C++11から basic_string のCoW(Copy on Write)実装が禁止された” からの混同か、まれに “C++11からは basic_string::data で内部文字列バッファにWriteアクセス可能?” という誤解を見かける気がする。今(C++11)も昔(C++98/03)も出来ません。