2016-02-04 14 views
13

を使用しているとき、私は、文字列を埋めるために文字の配列とも初期化リストを使用することができることを知っています。C++文字列 - 奇妙な行動初期化リストコンストラクタ

これは、コンパイラがinitializer_listまたはアロケータにint型からいくつかの暗黙的なプロモーションを行っていることになります。しかし、なぜそれが私に警告を与えてくれないのか、それが暗黙の理由を知らないのか分かりません。

あなたは、文字列のS4、およびS5で何が起こるか私に説明できますか?

http://ideone.com/5Agc2T

#include <iostream> 
#include <string> 
using namespace std; 

class A{ 
}; 

int main() { 

    // string::string(charT const* s) 
    string s1("12345"); 
    // 5 - because constructor takes into account null-terminated character 
    cout << s1.size() << endl;  

    // string(std::initializer_list<charT> ilist) 
    string s2({'1','2','3','4','5'}); 
    // 5 - because string is built from the contents of the initializer list init. 
    cout << s2.size()<<endl; 

    // string::string(charT const* s, size_type count) 
    string s3("12345",3); 
    // 3 - Constructs the string with the first count characters of character string pointed to by s 
    cout << s3.size() << endl; 

    // basic_string(std::initializer_list<CharT> init,const Allocator& alloc = Allocator()); - ? 
    string s4({'1','2','3','4','5'},3); 
    // 2 - why this compiles (with no warning) and what this result means? 
    cout << s4.size() << endl; 



    string s5({'1','2','3','4','5'},5); 
    // 0 - why this compiles (with no warning) and what this result means? 
    cout << s5.size() << endl; 

    // basic_string(std::initializer_list<CharT> init,const Allocator& alloc = Allocator()); 
    // doesn't compile, no known conversion for argument 2 from 'A' to 'const std::allocator<char>&' 
    //string s6({'1','2','3','4','5'},A()); 
    //cout << s6.size() << endl; 

    return 0; 
} 
+1

あなたが起こる代わりに何を期待するものを私に説明してもらえますか?私はこのコードで意図しない何かを見ることができません。 – dhein

+0

はい、もちろんです。私は両方のコンストラクタで同じ動作が期待されていますが、文字列とイニシャライザリストも同様です。 – tomekpe

答えて

28
string s6({'1','2','3','4','5'},3); 
string s7({'1','2','3','4','5'},5); 

実際には、これらの初期化は、単にstd::initializer_listコンストラクタを呼び出すことはありません。 2番目の引数は暗黙的にstd::allocatorに変換されないため、他のコンストラクタも考慮されます。 std::initializer_listコンストラクタは上記コンストラクタへother引数として渡すブレース-INIT-リストから一時的std::stringを作成するために使用され

basic_string(const basic_string& other, 
       size_type pos, 
       size_type count = std::basic_string::npos, 
       const Allocator& alloc = Allocator()); 

:と呼ばれるコンストラクタは、この署名を有するものです。一時参照は、それが参照への参照のためにバインドできます。二番目の引数は、したがって、サブコピー構築の出発点として使用されるpos引数、です。

だからs6間隔[3, 5)(すなわち"45")の文字であり、s7間隔[5,5)(すなわち"")の文字です。

+3

うわー。これらの落とし穴は、C++を手に入れるのが難しい場合の例です。 – kebs

+4

OPが期待していたことは他に何か分かりませんか? – dhein

+3

コンパイラは、 '5'から' const std :: allocator & 'への暗黙的な変換がないという不平を言うことを期待していました。 –