質問

C ++ 11以降、標準のライブラリコンテナと std::string Constructorsが初期化リストを取得しています。このコンストラクターは、他のコンストラクターよりも優先されます(コメントで @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'
}

このサイトで3番目の例を見つけることができませんでした、そして、ラウンジで物事が出てきましたu003CC++>チャット(@RightFold、@Abyx、@JerryCoffinとの議論)、やや驚くべきことは、 std::string コンストラクターは、使用するカウントとキャラクターを取得します {} それ以外の (), 、その意味をから変えます n キャラクターのコピー n-th文字(通常はASCIIテーブルから)に続いて他のキャラクターが続きます。

これは、変換の絞り込みに関する通常のブレース禁止によって捕らえられません。なぜなら、65は文字として表現できる一定の式であり、INTに戻ると元の値を保持するため(§8.5.4/7、弾丸4)(ありがとう) @jerrycoffinに)。

質問: :標準的なライブラリに潜んでいるより多くの例があります。 () スタイルコンストラクターへ {} スタイル、イニシャルリストコンストラクターによって貪欲に一致していますか?

役に立ちましたか?

解決

あなたの例で、私は仮定します std::vector<int>std::string あなたは他の容器もカバーするつもりでした、例えば std::list<int>, std::deque<int>, 、同じ問題を抱えているなど、明らかに、 std::vector<int>. 。同様に、 int 適用される唯一のタイプではありません char, short, long そして彼ら unsigned バージョン(おそらく他のいくつかの積分タイプも)。

あると思います std::valarray<T> しかし、私にはわかりません T 積分タイプになることが許可されています。実際、これらには異なるセマンティクスがあると思います。

std::valarray<double>(0.0, 3);
std::valarray<double>{0.0, 3};

他にもいくつかの標準C ++クラステンプレートがあります std::initializer_list<T> 議論として、しかし、これらのいずれかは、ブレースの代わりに括弧を使用するときに使用される過負荷コンストラクターを持っているとは思わない。

他のヒント

の発生を検索するだけです initializer_list.

  • すべてのシーケンスには、ベクターのようなコンストラクターがあります。

    • デク
    • ダイナレー
    • Forward_list
    • リスト
    • ベクター
  • ヴァレイ

  • BASIC_STRING

  • 順序付けられていないコレクションには、初期バケット数を決定するために整数を服用するコンストラクターがあります。

    • UNORDERED_SET
    • UNORDERED_MULTISET

それだけだと思います。

#include <unordered_set>
#include <iostream>

int main() {
    std::unordered_set<int> f (3);
    std::unordered_set<int> g {3};
    std::cout << f.size() << "/" << g.size() << std::endl; // prints 0/1.
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top