简体   繁体   English

boost :: bind,std :: bind和重载函数

[英]boost::bind, std::bind and overloaded functions

I noticed that boost::bind, unlike std::bind, can work with overloaded functions when one of these functions doesn't have any parameters. 我注意到,与std :: bind不同,boost :: bind可以在这些函数之一没有任何参数的情况下使用重载函数。 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
}

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. 我认为这只是实现细节的意外产物,我不认为Boost提供任何有关自动解决正确的重载的保证。

std::bind is a C++11 feature implemented with variadic templates. std::bind是使用可变参数模板实现的C ++ 11功能。

boost::bind was implemented for C++03, meaning that it relies on a large number of overloaded function templates. boost::bind是为C ++ 03实现的,这意味着它依赖于大量重载的函数模板。

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." Boost文档只说明了这一点:“尝试绑定重载函数通常会导致错误,因为无法确定要绑定哪个重载。”

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. 在我的书中,这意味着Boost文档会告诉您这是否行得通(编译)甚至选择正确的重载都是“未定义的行为”。

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. 据我所知,您应该始终使用显式static_cast转换( static_cast )修复希望选择的重载的签名。 This is true for both boost::bind and std::bind , and in that sense, both implementations agree. 对于boost::bindstd::bind都是如此,从这个意义上说,两个实现都同意。

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. 不过,我认为这不是故意的。

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 ). 第一种情况在带有stdboost MSVC10中都能很好地编译(因为MSVC10不支持可变参数模板,因此std::bind的实现与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. 第二种情况不会编译,因为bind可以解决具有不同Arity的重载,但不能解决仅因参数类型而异的重载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM