std::string::iterator は何型 ?

発端

Borland C++ Buider 6 で作っていたあるプログラムをgccでコンパイルしようとしたら、コンパイルが通らなかった。問題の箇所は一言で言うと、次のようなコードとなっていました。

std::string s;
// 中略br>

char *p = s.begin();
puts(p);

std::string::begin() の返す方は std::string::iterator 型であるので、この時点で相当阿漕なコードではあるのだが、それでも C++ Builder では何の問題もなくコンパイルできていた。
そこで、手元にあるコンパイラで上記のコードをコンパイルしてみた。

メーカー
製品
バージョン
STL
結果
Borland
C++ Builder 6 STLPort OK
Borland
C++ Builder
6
RogueWave
OK
Microsoft
Visual C++
6
Dikumware
OK
cygwin
g++
3.2
libstdc++
NG

実際の定義

実際の定義はどうなっているかというと

C++ Buider (STLPort)


template <class _CharT, class _Traits, class _Alloc> class basic_string
: protected _String_base<_CharT,_Alloc> {
...
typedef _CharT value_type;
...
typedef value_type* pointer;
typedef value_type* iterator;

}
よって string の場合、iterator は char * と同じ型となります。

C++ Builder 6 (RogueWave)

template <class charT, class traits , class Allocator >
class _RWSTDExportTemplate basic_string {

typedef charT* iterator;

}


となり string の場合、iterator は char * と同じ型となります。

Visual C++ 6 の場合


template<class _E,
class _Tr = char_traits<_E>,
class _A = allocator<_E> >
class basic_string {

typedef _A::pointer pointer;

typedef _A::pointer iterator;
}


となっており、allocator クラスでは
template<class _Ty>
class allocator {

typedef _Ty _FARQ *pointer;

}


となっているので、結局 string の場合は char * となります。

g++ の場合


template<typename _CharT, typename _Traits, typename _Alloc>
class basic_string {

typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;

}


となっており、結局 __gnu_cxx::__normal_iterator<pointer, basic_string>となっています。
これでは char * には(何かしらの変換関数が用意されていない限り)到底変換できません。

結論


[覚書] [トップページ]