将带有捕获的lambda传递给模板化函数

时间:2017-06-17 12:16:10

标签: c++ templates lambda capture std-function

我尝试使用模板化函数来包装任何布尔表达式或函数返回布尔值。

template<typename BOOL_COND>
bool calculate(const BOOL_COND& bool_cond)
{
  return !(!(bool_cond));
}

assert( calculate( true ) );
assert( calculate( 1 == 1 ) );
std::shared_ptr<int> ptr = std::make_shared<int>(11);
assert( calculate( ptr ) );
assert( calculate( []() { return 1 == 1;} ) );
assert( calculate( std::function<bool()>([]() { return std::string().empty();} )) );

std::function<bool(void)> f = [&]() -> bool { return ptr.get();};
assert( calculate( f ));
assert( calculate( std::function<bool(void)>([&]() -> bool { return ptr.get();} )) );

// assert( calculate( [&]() -> bool { return ptr.get();} ) ); // NOT WORK!!!


// clang-600.0.57 with -std=c++1y

如果没有显式转换为std :: function,我无法传递带捕获的lambda。是什么原因?有没有转换的解决方案?

模板专业化?如何?

1 个答案:

答案 0 :(得分:4)

您没有调用 lambda表达式生成的闭包,而只是使用$.get(),就好像它是bool_cond或者可以隐式转换为它。

您需要调用bool

bool_cond

template<typename BOOL_COND> bool calculate(const BOOL_COND& bool_cond) { return !(!(bool_cond())); } 有效的原因是它提供了implicit conversion operator bool

如果你想要&#34;制服&#34;对{em>函数对象和隐式可转换std::function都有效的calculate函数,你需要两个用bool约束的重载:

enable_if

使用C ++ 17:

template<typename BOOL_COND>
auto calculate(const BOOL_COND& bool_cond)
    -> std::enable_if_t<std::is_invokable_v<const BOOL_COND&>>
{
    return !(!(bool_cond()));
}

template<typename BOOL_COND>
auto calculate(const BOOL_COND& bool_cond)
    -> std::enable_if_t<!std::is_invokable_v<const BOOL_COND&>>
{
    return !(!(bool_cond));
}

只是略有关联,但我写了一篇文章,可能会以各种方式将函数/ lambdas传递给其他函数:"passing functions to functions"