首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >静态断言lambda捕获

静态断言lambda捕获
EN

Stack Overflow用户
提问于 2018-05-31 18:40:19
回答 3查看 345关注 0票数 0

目前我正在学习并行编程和元编程,我很难对捕获变量的lambda进行编译时检查。

假设我们有这样的代码:

代码语言:javascript
复制
#include <type_traits>
#include <functional>
#include <iostream>

int main(){

    auto non_capture = [](){
        std::cout<<"this lambda is not capturing!"<<std::endl;
    };

    auto capture = [&](){
        std::cout<<"this lambda is capturing"<<std::endl;
    };

    //value is true for this one
    static_assert(std::is_convertible<decltype(non_capture), std::function<void()>>::value, "message1");

    //i need help for this
    static_assert(is_lambda_that_captures<decltype(capture)>::value, "this is some error message");
}

我需要帮助来定义is_lambda_that_captures类型特征,这样我才能传递第二个静态断言。我该怎么做呢?

有一个针对最新标准的解决方案非常受欢迎(当前最新版本是c++17) :)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-05-31 19:02:04

对于C++17,您可以利用最新的特性:std::is_invocable。它对于捕获和非捕获lambda都应该可以很好地工作:

代码语言:javascript
复制
static_assert(std::is_invocable_v<decltype(noncapture)>,"Error?!");
static_assert(std::is_invocable_v<decltype(capture)>,"Error?!");

当然,它也适用于函数指针、std::function和所有可访问operator()的对象。如果你只想检测lambdas (我看不出它有多大用处),你需要更多的特征魔法。

票数 3
EN

Stack Overflow用户

发布于 2018-05-31 18:55:41

这是我的解决方案。它依赖于两个原则:

  1. 非capuring lambda可转换为函数指针。
  2. 所有lambda均可转换为lambda

代码语言:javascript
复制
#include <type_traits>
#include <functional>
#include <iostream>

template<class T, class Ret, class...Args>
struct is_non_capture_lambda : std::is_convertible<T, Ret (*)(Args...)>
{

};

template<class T, class Ret, class...Args>
struct is_capture_lambda
{
    static constexpr auto convertible = std::is_convertible<T, std::function<Ret(Args...)>>::value;
    using type = bool;
    static constexpr auto value = convertible && !is_non_capture_lambda<T, Ret, Args...>::value;


};

int main(){

    auto non_capture = [](){
        std::cout<<"this lambda is not capturing!"<<std::endl;
    };

    auto capture = [&](){
        std::cout<<"this lambda is capturing"<<std::endl;
    };

    //value is true for this one
    static_assert(is_non_capture_lambda<decltype(non_capture), void>::value, "message1");

    //i need help for this
    static_assert(is_capture_lambda<decltype(capture), void>::value, "this is some error message");
}
票数 4
EN

Stack Overflow用户

发布于 2018-05-31 18:56:24

首先,请注意

代码语言:javascript
复制
static_assert(
    std::is_convertible<decltype(capture), std::function<void()>>::value, 
    "msg");

也会通过。任何lambda都可以转换为适当类型的std::function。捕获lambda和非捕获lambda之间的区别在于,非捕获lambda可以转换为指向函数的指针。所以:

代码语言:javascript
复制
 static_assert(
     std::is_convertible<decltype(non_capture), void (*)()>>::value, 
     "msg");

都会过去,但是

代码语言:javascript
复制
 static_assert(
     std::is_convertible<decltype(capture), void (*)()>>::value, 
     "msg");

都会失败。您可以使用std::is_class区分非捕获的lambda和实际的函数指针(但我想不出您为什么要这样做)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50622379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档