是否可以使用附加参数将 std::bind 重新绑定到另一个函数

问题描述

假设您有一些使用 std::bind 和一些有界参数包装的函数

void func1(std::string& arg1,std::unique_ptr<int>& arg2)
{
    ...
}
...

auto f1 = std::bind(func1,std::string{"message"},std::make_unique<int>(123));

现在,想象一下,无论出于何种原因,您想将此对象重新绑定到具有一些附加参数的另一个函数,例如:

void func2(std::exception& ex,std::string& arg1,std::unique_ptr<int>& arg2)
{
    ...
}
...

try {
    f1();
} catch (std::exception& ex) {
    auto f2 = some_magical_rebind(func2,std::move(ex),args_of(f1));
}

可以这样做吗?由于 std::bind 在内部使用 std::tuple 来打包参数,因此它认为应该是可能的。

解决方法

std::bind 的返回值具有非常有限的功能(存储绑定参数、根据存储的参数进行复制/移动、可调用以及检测是否返回 std::bind 的能力),以及提取绑定参数不是其接口的一部分。所以没有办法用 std::bind 做你想做的事。您需要构建自己的 std::bind 形式,以提供您感兴趣的界面。

,

只需将参数存储在变量中并使用更通用的 std::function 而不是 std::bind 结果的自动:

auto msg = std::string( "message" );
auto ptr = std::make_unique<int>( 123 );
std::function<void()> f = std::bind( func1,std::ref( msg ),std::ref( ptr ) );


try {
    f();
}
catch( std::exception& ex) {
    f = std::bind( func2,ex,std::ref( ptr ) );
}

或者您可以将它们打包成一个结构或 std::tuple(如果您愿意)。