【问题标题】:Is it possible to rebind the std::bind to another function with additional arguments是否可以使用附加参数将 std::bind 重新绑定到另一个函数
【发布时间】:2021-02-13 21:28:16
【问题描述】:

假设您有一些使用 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::tuple 来打包参数" 这是标准绝不要求的实现细节。
  • 您有什么问题 - 将另一个函数重新绑定到 f1 或提取 func1() 的参数?
  • 当且仅当您设计自己的函数和参数持有者对象时才有可能,例如使用 std::tuple。
  • 我对这个问题的前提感到困惑。 try-catch 块的上下文是否知道f1 的签名(f2 很明显)?那为什么要绑定参数呢?

标签: c++ c++11 stdbind


【解决方案1】:

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

【讨论】:

  • 我认为这个特殊问题可以比实现你自己的std::bind 变体更容易解决:)
  • 几乎任何问题都可以通过不使用std bind来解决。
  • 这里甚至不用std::bind,而是自己写。
【解决方案2】:

只需将参数存储在变量中并使用更通用的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( msg ), std::ref( ptr ) );
}

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

【讨论】:

  • 这不会从f 中提取参数,而是依赖仍在范围内的参数。
猜你喜欢
  • 1970-01-01
  • 2015-07-14
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-29
相关资源
最近更新 更多