boost::bind, std::bind and overloaded functions

余生长醉 提交于 2019-12-31 03:39:14

问题


I noticed that boost::bind, unlike std::bind, can work with overloaded functions when one of these functions doesn't have any parameters. Am I right? Is this documented?

#include <boost/bind.hpp>

#include <functional>
#include <iostream>

void foo()
{
    std::cout << "::foo() \n";
}

void foo(int)
{
    std::cout << "::foo(int) \n";
}

int main()
{
    boost::bind(foo)(); // Ok
    boost::bind(foo, 0)(); // Ok

    // std::bind(foo)(); // Error
    // std::bind(foo, 0)(); // Error
}

#include <boost/bind.hpp>

#include <functional>
#include <iostream>

void foo(int)
{
    std::cout << "::foo(int) \n";
}

void foo(const std::string&)
{
    std::cout << "::foo(const std::string&) \n";
}

int main()
{
    // boost::bind(foo, 0)(); // Error
    // boost::bind(foo, "str")(); // Error

    // std::bind(foo, 0)(); // Error
    // std::bind(foo, "str")(); // Error
}

回答1:


I would assume it is just an unintended artifact of the implementation details, I don't think Boost provides any guarantees about automatically resolving the correct overload.

std::bind is a C++11 feature implemented with variadic templates.

boost::bind was implemented for C++03, meaning that it relies on a large number of overloaded function templates.

The two are quite different in their implementation details, and so, I would assume any difference between their behavior is a consequence of that, rather than an intentional and specified difference.

The Boost documentation only states this: "An attempt to bind an overloaded function usually results in an error, as there is no way to tell which overload was meant to be bound."

In my book, this means that Boost docs tell you that it is "undefined behavior" whether or not this will work (compile) or even select the correct overload.

And as far as I know, you should always use an explicit cast (static_cast) to fix the signature of the overload that you wish to select. This is true for both boost::bind and std::bind, and in that sense, both implementations agree.




回答2:


It is somewhat documented as part of the "Interfaces" -> "Synopsis" part, where the overloads are listed. As you can see there, Boost does not use variadic templates, hence when given those overload, explicitly these:

template<class R> unspecified-2 bind(R (*f) ());
template<class F, class A1> unspecified-3-1 bind(F f, A1 a1);
template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1);

the compiler prefers the overloaded versions with an empty argument list over others as it is a better match. I don't think this was intentional, though.




回答3:


The first case compiles well in MSVC10 with both std and boost (because MSVC10 doesn't support variadic templates, so std::bind is implemented similarly to boost::bind).

The second case wouldn't compile, because bind can resolve overloads having different arity, but can't resolve overloads that differ by argument types only.



来源:https://stackoverflow.com/questions/19217353/boostbind-stdbind-and-overloaded-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!