Quais exemplos de lista de inicializadores ávidos estão à espreita na Biblioteca Padrão?
Desde o C ++ 11, os contêineres da Biblioteca Padrão estd::string
ter construtores usando uma lista de inicializadores. Esse construtor tem precedência sobre outros construtores (mesmo, como apontado por @ JohannesSchaub-litb nos comentários, mesmo ignorando outros critérios de "melhor correspondência"). Isso leva a algumas armadilhas bem conhecidas ao converter todos os parênteses()
formas de construtores para suas versões escoradas{}
#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'
}
Eu não consegui encontrar o terceiro exemplo neste site, e a coisa surgiu no bate-papo do Lounge <C ++> (em discussão com @rightfold, @Abyx e @JerryCoffin). O mais surpreendente é que a conversão dostd::string
construtor levando uma contagem e um caractere para usar{}
ao invés de()
, muda seu significado den
cópias do personagem para on
-ésimo caractere (normalmente da tabela ASCII) seguido pelo outro caractere.
Isso não é detectado pela proibição usual de restrição de conversões, porque 65 é uma expressão constante que pode ser representada como um char e manterá seu valor original quando convertido de volta para int (§8.5.4 / 7, item 4) (obrigado para @JerryCoffin).
Questão: há mais exemplos à espreita na Biblioteca Padrão, onde a conversão de um()
construtor de estilo para{}
estilo, é correspondido avidamente por um construtor de lista de inicializadores?