tipo de retorno de std::bind implícitamente convertible a dos constructores explícitos diferentes
Frecuentes
Visto 1,516 veces
1
Dado dos explicit
constructor overloads (based on different std::function<...>
types), the return value of std::bind
es capaz de seleccionar ya sea (thereby making the call ambiguous)
call of overloaded ‘Bar(std::_Bind_helper<false, void (Foo::*)(int),
Foo*, int>::type)’ is ambiguous
If I comment out either, then the code compiles!
I would have thought making the constructors explicit
would have either selected the correct overload, or prevented both from being selected?
Por supuesto explícitamente creando un std::function
at the point I bind works:
Bar b(std::function<void(int)>(std::bind((&Foo::process), &f, 1)));
However, I'm puzzled as to why type deduction doesn't work?
- If the return value from
std::bind
matches neither of the two constructor signatures, the fact they areexplicit
should prevent both from being selected. - If the return value from
std::bind
matches one of the two constructor signatures, the fact they areexplicit
should cause the correct one to be selected.
¿Qué está pasando realmente aquí?
Full working code below:
#include <functional>
struct Foo
{
void process(int) { }
};
struct Bar
{
// comment out either of these to compile
explicit Bar(std::function<void(int)>) {}
explicit Bar(std::function<void(short)>) {}
};
int main()
{
Foo f;
Bar b(std::bind(&Foo::process, &f, 1));
return 0;
}
1 Respuestas
4
Haciendo el constructor explicit
has nothing to do with the arguments having to match exactly! The affect of making a constructor explicit means that it won't be used to implicitly convert an object of a different type the type Bar
using this constructor. However, if you try to initialize a Bar
object using direct initialization (i.e., Bar(x)
), both constructors will be considered.
El resultado de std::bind()
ciertamente no es un std::function<Signature>
, i.e., it doesn't match either of your constructors exactly. Since there is a non-explicit
constructor para std::function<Signature>
which works for function objects, both signatures do match: the produced bind expression doesn't require any parameter but it can take arguments, i.e., any argument type also cannot be used to distinguish which of the two constructors of Bar
should match. Even if the bind expression would require one argument, I don't think it would be used to prefer one constructor over another.
Respondido el 22 de Septiembre de 13 a las 01:09
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c++ c++11 std-function stdbind or haz tu propia pregunta.