std :: to_string – mais do que a instância da function sobrecarregada corresponde à lista de argumentos

counter é um int

 void SentryManager::add(std::string name,std::shared_ptr){ name = name + std::to_string(counter); } 

Qual seria a melhor maneira de parar esse erro? Quando eu estava sendo preguiçoso eu apenas fiz o int long long (ou algo assim), mas tenho certeza que existe uma maneira melhor de resolver isso.

Mensagem de erro:

 sentrymanager.cpp(8): error C2668: 'std::to_string' : ambiguous call to overloaded function 

Eu estou usando o Visual C ++ 2010 Express.

No VC ++ 2010 existem três sobrecargas de std::to_string que demoram long long , unsigned long long e long double , respectivamente – claramente int não é nenhuma destas, e nenhuma conversão é melhor que outra ( demo ), então a conversão não pode ser feito de forma implícita / inequívoca.

Em termos de suporte real ao C ++ 11, esta é uma falha por parte da implementação da biblioteca padrão do VC ++ 2010 – o próprio padrão C ++ 11 requer nove sobrecargas de std::to_string ([string.conversions] / 7) :

 string to_string(int val); string to_string(unsigned val); string to_string(long val); string to_string(unsigned long val); string to_string(long long val); string to_string(unsigned long long val); string to_string(float val); string to_string(double val); string to_string(long double val); 

Se todas essas sobrecargas estivessem presentes, obviamente você não teria esse problema; no entanto, o VC ++ 2010 não foi baseado no padrão C ++ 11 (que ainda não existia no momento de seu lançamento), mas sim no N3000 (de 2009 ), que não exige essas sobrecargas adicionais. Consequentemente, é duro culpar muito o VC ++ aqui …

Em qualquer caso, por apenas um punhado de chamadas, não há nada de errado em usar um casting para resolver a ambiguidade:

 void SentryManager::add(std::string& name, std::shared_ptr) { name += std::to_string(static_cast(counter)); } 

Ou, se houver uso pesado de std::to_string em sua base de código, escreva alguns wrappers e use-os – dessa forma, nenhuma conversão de site de chamada é necessária:

 #include  #include  template inline typename std::enable_if::value && std::is_signed::value, std::string>::type to_string(T const val) { return std::to_string(static_cast(val)); } template inline typename std::enable_if::value && std::is_unsigned::value, std::string>::type to_string(T const val) { return std::to_string(static_cast(val)); } template inline typename std::enable_if::value, std::string>::type to_string(T const val) { return std::to_string(static_cast(val)); } // ... void SentryManager::add(std::string& name, std::shared_ptr) { name += to_string(counter); } 

Não consigo verificar se o VC ++ 2010 é bem-sucedido ou falha com o uso acima de SFINAE; se falhar, o seguinte – usando o despacho de tags em vez de SFINAE – deve ser compilável (se potencialmente menos claro):

 #include  #include  namespace detail { template // is_float is_unsigned inline std::string to_string(T const val, std::false_type, std::false_type) { return std::to_string(static_cast(val)); } template // is_float is_unsigned inline std::string to_string(T const val, std::false_type, std::true_type) { return std::to_string(static_cast(val)); } template // is_float inline std::string to_string(T const val, std::true_type, _) { return std::to_string(static_cast(val)); } } template inline std::string to_string(T const val) { return detail::to_string(val, std::is_floating_point(), std::is_unsigned()); } 

Você tropeçou em C ++ DR 1261 , que lê em parte

O código ” int i; to_string(i); ” não é compilado, pois ‘ int ‘ é ambíguo entre ‘ long long ‘ e ‘ long long unsigned ‘. Não parece razoável esperar que os usuários to_string números para um tipo maior apenas para usar to_string .

A resolução proposta é adicionar mais sobrecargas. O GCC já implementou isso ; Eu acho que o MSVC não tem.