我想像这样声明一个函数:
template <typename Lambda>
int foo(Lambda bar) {
if(/* check bar is null lambda */)
return -1;
else
return bar(3);
}
int main() {
std::cout << foo([](int a)->int{return a + 3;}) << std::endl;
std::cout << foo(NULL_LAMBDA) << std::endl;
}
那么,我如何声明NULL_LAMBDA
和检查传递的lambda函数的条件是否为空?
发布于 2017-08-17 14:30:50
您可以添加专用专业化认证:
#include <iostream>
#include <cstddef>
template<typename Lambda> int
foo(Lambda bar)
{
return(bar(3));
}
template<> int
foo<::std::nullptr_t>(::std::nullptr_t)
{
return(-1);
}
int main()
{
::std::cout << foo([] (int a) -> int {return(a + 3);}) << ::std::endl;
::std::cout << foo(nullptr) << ::std::endl;
}
发布于 2017-08-18 13:34:08
Lambda是一种类型,而不是一种类型。
我们可以这样做:
struct null_callable_t{
template<class...Ts>
constexpr void operator()(Ts&&...)const{}
explicit constexpr operator bool()const{return false;}
constexpr null_callable_t() {}
friend constexpr bool operator==(::std::nullptr_t, null_callable_t ){ return true; }
friend constexpr bool operator==(null_callable_t, ::std::nullptr_t ){ return true; }
friend constexpr bool operator!=(::std::nullptr_t, null_callable_t ){ return false; }
friend constexpr bool operator!=(null_callable_t, ::std::nullptr_t ){ return false; }
};
constexpr null_callable_t null_callable{};
现在我们的代码变成:
template <typename Lambda>
int foo(Lambda bar) {
if(!bar)
return -1;
else
return bar(3);
}
这很巧妙:
std::cout << foo([](int a) {return a + 3;}) << std::endl;
std::cout << foo(null_callable) << std::endl;
发布于 2021-02-08 12:39:33
注意,在C++17中,我们可以这样写:
template<typename Lambda>
int foo(Lambda bar)
{
if constexpr (std::is_same_v<std::decay_t<Lambda>, std::nullptr_t>)
return -1;
else if constexpr (std::is_convertable_v<Lambda, bool>)
{
if (bar)
return bar(3);
else
return -1;
}
else
return bar(3);
}
我想在C++20中我们可以定义一个std::invocable (概念头)或nulltpr_t来约束Lambda的概念。
https://stackoverflow.com/questions/45727933
复制相似问题