14

C++11 以降、標準ライブラリ コンテナーにstd::stringは、イニシャライザー リストを使用するコンストラクターがあります。このコンストラクターは、他のコンストラクターよりも優先されます (コメントで @JohannesSchaub-litb が指摘したように、他の「最適な一致」基準を無視しても)。()これは、括弧で囲まれた形式のコンストラクターをすべて波括弧付きのバージョンに変換するときに、いくつかのよく知られた落とし穴につながります。{}

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>

void print(std::vector<int> const& v)
{
    std::copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, ","));
    std::cout << "\n";
}

void print(std::string const& s)
{
    std::cout << s << "\n";
}

int main()
{
    // well-known 
    print(std::vector<int>{ 11, 22 });  // 11, 22, not 11 copies of 22
    print(std::vector<int>{ 11 });      // 11,     not 11 copies of 0

    // more surprising
    print(std::string{ 65, 'C' });      // AC,     not 65 copies of 'C'
}

std::stringこのサイトで 3 番目の例を見つけることができませんでした。Lounge<C++> チャット (@rightfold、@ Abyx 、@JerryCoffin との議論) で話題になりました。の{}代わりに使用する文字は、その文字のコピーから- 番目の文字 (通常は ASCII テーブルから) に()その意味を変更し、その後に他の文字が続きます。nn

65 は char として表すことができ、int に変換されたときに元の値を保持する定数式であるため (§8.5.4/7、箇条書き 4) (ありがとう@JerryCoffinへ)。

質問():スタイル コンストラクターを{}スタイルに変換し、初期化子リスト コンストラクターによって貪欲に一致する標準ライブラリに潜んでいる例は他にありますか?

4

2 に答える 2