2011-01-21 13 views
5

mi código de problema:C++ sobrecarga: cadena literal vs. impulso :: función de ambigüedad

#include <string> 
#include <boost/function.hpp> 

void func (const std::string&) {} 
void func (const boost::function<void()>&) {} 

int main() { 
    func (main); // good 
    func ("bad"); 
    return 0; 
} 

=>

error: call of overloaded ‘func(const char [4])’ is ambiguous 
overload.cpp:4: note: candidates are: void func(const std::string&) 
overload.cpp:5: note:     void func(const boost::function<void()()>&) 

Sé que podría resolver este llamando explícitamente func (cadena ("malo ")); o proporcionando un func (const char *), pero me pregunto si hay una manera de mantener el lado de la persona que llama como en el ejemplo y sin introducir más sobrecargas.

Quizás algo con boost :: enable_if? Gracias por cualquier pista.

+0

¿De verdad crees que la causa es la sobrecarga que tiene 'boost :: function', ¿has intentado por ejemplo compilar sin esa sobrecarga? ¿Eso funcionará? – Nim

+1

sí, es causado por la función boost ::. El ejemplo que publiqué reproduce toda la situación. – denis

+0

sí - no hice la prueba antes de preguntar, simplemente un poco desconcertado de que este fuera el caso - parece que es ... mmm ... corto de proporcionar sobrecargas para todo, no estoy seguro de que haya una solución clara para esto ... – Nim

Respuesta

4

Usted no puede resolver fácilmente este. boost::function<> y std::function<> no admiten solo funtores invocables por f(), sino también un puntero a miembros llamables por (secondArg.*firstArg)() y miembros de datos, por lo que sus constructores básicamente absorben todo y luego deciden qué hacer con el tipo.

No es trivial escribir una clase de prueba SFINAE que proteja de las conversiones implícitas (y ni siquiera estoy seguro de si sería posible, ya que la biblioteca estándar no lo hace. alguna razón). Recuerde que un tipo puede ser invocable debido a muchas propiedades diferentes; puede tener una función de conversión para funcionar con un tipo de puntero, etc. pp. Escribir una clase SFINAE que podría hacer que este trabajo signifique rechazar una conversión implícita en algunos casos y aceptar una conversión implícita en otros casos basados ​​en propiedades realmente no obvias.

Si desea evitar esta ambigüedad, trataría simplemente de elegir un nombre de función diferente o si se trata de un problema de una sola vez, haga el casting por el lado de la persona que llama.

+1

Pregunta anterior, pero para los lectores futuros hay un informe de defectos sobre esto para 'std :: function'. Ver [2132. std :: function ambiguity] (http://cplusplus.github.io/LWG/lwg-active.html#2132) que se implementa actualmente en g ++ 4.8. –

0

añadir lo siguiente:

void func (const char *s) { func(string(s)); } 

actualización

template<class A0, ...> 
void func (const A0 &a0, ...) { 
    func(argize(a0), ...); // convert chars to strig, otherwise jut pass 
} 
+0

el problema es decir, el código se generará automáticamente y posiblemente ya haya muchas sobrecargas, como func (cadena); func (cadena, int); func (cadena, int, impulso :: función) y así sucesivamente. Por lo tanto, la adición de char * -overloads lamentablemente no es una opción. – denis

+0

@denis ver la actualización – Anycorn