Weird function call results
I got an overloaded function: void f(int n) { std::clog << "invoked f(int n = " << n << ")" << std::endl; } void f(double d) { std::clog << "invoked f(double d = " << d << ")" << std::endl; } If I put declarations in that order: void (*f_int)(int) = &f; void (*f_double)(double) = &f; BOOST_PYTHON_MODULE(test) { def("f", f_int); def("f", f_double); } No matter what I pass into the function f, f(double) is invoked every time. Even though I call f(int(1)) I will see "invoked f(double d = 1)". But if I declare the function f in reversed order: BOOST_PYTHON_MODULE(test) { def("f", f_double); def("f", f_int); } I will see "invoked f(int n = 5)" when I call f(5) and "invoked f(double d = 3.14)" when I call f(3.14) as it has to be. Why does it happen? Why does it depend on declaration order? -- Ilya.
On 18/12/14 06:13 AM, ilias wrote:
I got an overloaded function:
void f(int n) { std::clog << "invoked f(int n = " << n << ")" << std::endl; }
void f(double d) { std::clog << "invoked f(double d = " << d << ")" << std::endl; }
If I put declarations in that order:
void (*f_int)(int) = &f; void (*f_double)(double) = &f;
BOOST_PYTHON_MODULE(test) { def("f", f_int); def("f", f_double); }
No matter what I pass into the function f, f(double) is invoked every time. Even though I call f(int(1)) I will see "invoked f(double d = 1)".
But if I declare the function f in reversed order:
BOOST_PYTHON_MODULE(test) { def("f", f_double); def("f", f_int); }
I will see "invoked f(int n = 5)" when I call f(5) and "invoked f(double d = 3.14)" when I call f(3.14) as it has to be. Why does it happen? Why does it depend on declaration order?
It definitely shouldn't. If it does, please submit a bug report including the test, as well as details as to what compiler and OS you were observing the error on. Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin...
On 12/19/14 5:34 AM, Stefan Seefeld wrote:
But if I declare the function f in reversed order:
BOOST_PYTHON_MODULE(test) { def("f", f_double); def("f", f_int); }
I will see "invoked f(int n = 5)" when I call f(5) and "invoked f(double d = 3.14)" when I call f(3.14) as it has to be. Why does it happen? Why does it depend on declaration order?
It definitely shouldn't. If it does, please submit a bug report including the test, as well as details as to what compiler and OS you were observing the error on.
It's not a bug, it's as designed. Boost.python tries function overloads in reverse registration order and picks the first one that works, in the sense that all the arguments convert. Alex
On 12/26/14 2:12 AM, ilias wrote:
It's not a bug, it's as designed. Boost.python tries function overloads in reverse registration order and picks the first one that works, in the sense that all the arguments convert.
Is that behavior specified somewhere in the documentation?
I'm not sure it is. It ought to be. It is mentioned on the TODO page where it discusses changing this behavior. http://www.boost.org/doc/libs/1_57_0/libs/python/todo.html#best-match-overlo... If the behavior was changed it would surely break existing code. The current behavior is at least straightforward to reason about, and we've been able to get most cases to work (even tricky ones) by carefully arranging the registration order. For the rare case where a single order doesn't work, we simply write a lightweight wrapper that takes boost::python::object args and do the introspection and dispatch manually. Sometimes we have this generic overload as a "fallback" that we register first, letting boost.python handle the simple cases when it can. Alex
participants (3)
-
Alex Mohr -
ilias -
Stefan Seefeld