将带捕获的 lambda 传递给模板函数
pass a lambda with capture to a templated 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。是什么原因?有没有不转换的解决方案?
模板专业化??怎么样?
您没有调用由 lambda 表达式 生成的闭包,而只是使用 bool_cond
就好像它是 bool
或隐式转换为它。
您需要改为调用 bool_cond
:
template<typename BOOL_COND>
bool calculate(const BOOL_COND& bool_cond)
{
return !(!(bool_cond()));
}
std::function
起作用的原因是它提供了一个 implicit conversion operator bool
.
如果您想要一个既适用于 函数对象 又可隐式转换 bool
的 "uniform" calculate
函数,您将需要两个用 enable_if
:
约束的重载
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));
}
使用 C++17:
template<typename BOOL_COND>
bool calculate(const BOOL_COND& bool_cond)
{
if constexpr(std::is_invokable_v<const BOOL_COND&>)
{
return !(!(bool_cond()));
}
else
{
return !(!(bool_cond));
}
}
仅略有相关,但我写了一篇文章,您可能会对将 functions/lambdas 传递给其他函数的各种方式感兴趣:"passing functions to functions".
我尝试使用模板函数来包装任何返回布尔值的布尔表达式或仿函数。
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。是什么原因?有没有不转换的解决方案?
模板专业化??怎么样?
您没有调用由 lambda 表达式 生成的闭包,而只是使用 bool_cond
就好像它是 bool
或隐式转换为它。
您需要改为调用 bool_cond
:
template<typename BOOL_COND>
bool calculate(const BOOL_COND& bool_cond)
{
return !(!(bool_cond()));
}
std::function
起作用的原因是它提供了一个 implicit conversion operator bool
.
如果您想要一个既适用于 函数对象 又可隐式转换 bool
的 "uniform" calculate
函数,您将需要两个用 enable_if
:
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));
}
使用 C++17:
template<typename BOOL_COND>
bool calculate(const BOOL_COND& bool_cond)
{
if constexpr(std::is_invokable_v<const BOOL_COND&>)
{
return !(!(bool_cond()));
}
else
{
return !(!(bool_cond));
}
}
仅略有相关,但我写了一篇文章,您可能会对将 functions/lambdas 传递给其他函数的各种方式感兴趣:"passing functions to functions".