sobrecarga sencillos poo operadores funciones ejemplos c++ c++11 initializer-list ambiguous

poo - sobrecarga de operadores en c++ ejemplos sencillos



la llamada de sobrecargada<lista de inicialización incluida con llaves> es ambigua, ¿cómo lidiar con eso? (1)

Este era sutil.

std::vector tiene un constructor que toma dos iteradores de rango. Es un constructor de plantillas (definido en 23.6.6.2 del estándar C ++ 11):

template<typename InputIterator> vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type());

Ahora, el constuctor de std::vector<wstring> acepta una std::vector<wstring> no es una coincidencia para la conversión implícita en su llamada de función ( const char* y string son tipos diferentes); pero el anterior, que por supuesto se incluye tanto en std::vector<string> como en std::vector<wstring> , es una coincidencia potencialmente perfecta, ya que se puede deducir que InputIterator es const char* . A menos que se use alguna técnica de SFINAE para verificar si el argumento de la plantilla deducida satisface el concepto InputIterator para el tipo subyacente del vector, que no es nuestro caso, este constructor es viable.

Pero, de nuevo, tanto std::vector<string> como std::vector<wstring> tienen un constructor viable que realiza la conversión de la lista de inicializadores reforzados: por lo tanto, la ambigüedad.

Entonces, el problema está en el hecho de que aunque "apple" y "banana" no son realmente iteradores (*), terminan siendo vistos como tales. Agregar un argumento "joe" a la función llamada corrige el problema al desambiguar la llamada, porque eso obliga al compilador a descartar los constructores basados ​​en rango y elegir la única conversión viable ( initializer_list<wstring> no es viable porque const char* no puede ser convertido a wstring ).

* En realidad, son punteros a caracteres const char , por lo que incluso podrían verse como iteradores constantes para los personajes , pero definitivamente no para cadenas, como nuestro constructor de plantillas está dispuesto a pensar.

Realmente no entiendo esto, pensé que el compilador primero ejecuta lo que está entre llaves y luego da el resultado a la función más apropiada. Aquí parece que le da a la función una lista de inicializadores para tratarla ...

#include <string> #include <vector> using namespace std; void func(vector<string> v) { } void func(vector<wstring> v) { } int main() { func({"apple", "banana"}); }

error:

<stdin>: In function ''int main()'': <stdin>:11:27: error: call of overloaded ''func(<brace-enclosed initializer list>)'' is ambiguous <stdin>:11:27: note: candidates are: <stdin>:6:6: note: void func(std::vector<std::basic_string<char> >) <stdin>:8:6: note: void func(std::vector<std::basic_string<wchar_t> >)

¿Por qué no se llama a mi sobrecarga func(vector<string> v) , y puedo hacerlo así?