Domanda

Da C ++ 11, i contenitori della libreria standard e std::string hanno costruttori che prendono un elenco iniziale. Questo costruttore ha la precedenza su altri costruttori (anche, come sottolineato da @JohannessChaub-Litb nei commenti, ignorando persino altri criteri di "migliore corrispondenza"). Questo porta ad alcune note note quando si converte tutti tra parentesi () forme di costruttori nelle loro versioni rinforzate {}

#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'
}

Non sono riuscito a trovare il terzo esempio su questo sito e la cosa è venuta nel saloneu003CC++> Chat (in discussione con @Rightfold, @abyx e @jerrycoffin), la cosa in qualche modo sorprendente è che convertire il std::string costruttore che prende un conteggio e un personaggio da usare {} invece di (), cambia il suo significato da n copie del personaggio al n-th carattere (in genere dalla tabella ASCII) seguito dall'altro personaggio.

Ciò non è catturato dal solito divieto di tutore per restringere le conversioni, perché 65 è un'espressione costante che può essere rappresentata come un carattere e manterrà il suo valore originale quando viene convertito in int (§8.5.4/7, Bullet 4) (grazie a @jerrycoffin).

Domanda: ci sono più esempi in agguato nella libreria standard in cui convertire a () costruttore di stile a {} Stile, è avidamente abbinato da un costruttore di prima lista?

È stato utile?

Soluzione

Presumo, con i tuoi esempi per std::vector<int> e std::string intendevi coprire anche gli altri contenitori, ad esempio, std::list<int>, std::deque<int>, ecc. Che hanno lo stesso problema, ovviamente, come std::vector<int>. Allo stesso modo, il int non è l'unico tipo in quanto si applica anche a char, short, long e il loro unsigned versione (forse anche alcuni altri tipi integrali).

Penso che ci sia anche std::valarray<T> Ma non sono sicuro se T è consentito essere tipo integrale. In realtà, penso che questi abbiano una semantica diversa:

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

Ci sono alcuni altri modelli di classe C ++ standard che prendono un std::initializer_list<T> Come argomento, ma non credo che nessuno di questi abbia un costruttore sovraccarico che verrebbe usato quando si usa parentesi anziché parentesi graffe.

Altri suggerimenti

Sto solo cercando l'eccezione di initializer_list.

  • Tutte le sequenze, hanno i costruttori come quello di Vector:

    • Deque
    • Dynarray
    • forward_list
    • elenco
    • vettore
  • Valarray

  • base_string

  • Collezioni non ordinate, esiste un costruttore che richiede un numero intero per determinare il conteggio iniziale del secchio.

    • UNORDERD_SET
    • UNORDED_MULTISET

Penso che sia tutto.

#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.
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top