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

时间:2013-10-07 04:58:34

标签: c++ boost c++11 boost-bind

我注意到boost :: bind与std :: bind不同,当其中一个函数没有任何参数时,它可以用于重载函数。我对吗?这有记录吗?

#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
}

3 个答案:

答案 0 :(得分:3)

我认为它只是实现细节的一个意外的工件,我不认为Boost提供任何关于自动解决正确重载的保证。

std::bind是使用可变参数模板实现的C ++ 11功能。

boost::bind是为C ++ 03实现的,这意味着它依赖于大量重载的函数模板。

两者在实施细节上有很大差异,因此,我认为他们的行为之间存在任何差异,而不是故意和指定的差异。

Boost文档仅说明了这一点: “尝试绑定重载函数通常会导致错误,因为无法判断哪个重载意味着绑定。”

在我的书中,这意味着Boost文档会告诉您这是“未定义的行为”,无论这是否有效(编译),甚至选择正确的重载。

据我所知,你应该总是使用一个显式的强制转换(static_cast)来修复你想要选择的重载的签名。对于boost::bindstd::bind都是如此,从这个意义上说,两种实现都是一致的。

答案 1 :(得分:2)

它在某种程度上被记录为“接口”的一部分 - &gt; “概要”部分,列出了重载。正如你在那里看到的那样,Boost确实使用可变参数模板,因此当给出那些重载时,明确指出:

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);

编译器更喜欢带有空参数列表的重载版本,因为它是更好的匹配。不过,我认为这不是故意的。

答案 2 :(得分:1)

第一个案例在MSVC10中使用stdboost编译良好(因为MSVC10不支持可变参数模板,因此std::bindboost::bind类似地实现)。

第二种情况不会编译,因为bind可以解决具有不同arity的重载,但不能解析仅因参数类型而不同的重载。