账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    lambda和std :: function之间的强制转换(关于结构继承自身偏特化版本)
    58
    0

    关于C++ 特性不太熟悉,谷歌也因为不知道具体关键字而造成困难,于是又来请教大家。

    代码是关于 lambda和std :: function之间的 无法进行强制转换 ,于是手动识别lambda 进行转换。

    下面这里的结构体function_traits继承一个偏特化的版本是什么意思?

    template <typename Function>
    struct function_traits : public function_traits<decltype(&Function::operator())> {
    
    };

    原文链接(需fan墙):http://vitiy.info/c11-functional-decomposition-easy-way-to-do-aop/

    测试代码(备注均为我自己添加,可能有错误)
    #include <iostream>
    #include <functional>
    
    //using namespace std;
    
    template <typename ...Args>
    std::function<void(Args...)> wrapLog(std::function<void(Args...)> f) {
    
        return [f](Args... args) {                                            //捕获函数对象f
            std::cout << "start" << std::endl;
            f(args...);
            std::cout << "finish" << std::endl;
        };
    }
    
    template <typename Function>
    struct function_traits : public function_traits<decltype(&Function::operator())> {
    
    };
    
    //lambda 转换为 std::function<void(Args...)> 需要知道 传入参数类型和返回值类型 ,这里进行萃取 
    template <typename ClassType, typename ReturnType, typename... Args>
    struct function_traits<ReturnType(ClassType::*)(Args...) const>         //Args...可变模板参数 ,因为不知道lambda将传入几个参数
    {
        //typedef ReturnType (*pointer)(Args...);
        typedef std::function<ReturnType(Args...)> function;            
    };
    
    
    template <typename Function>
    typename function_traits<Function>::function    //返回值类型 function_traits<Function>::function
    to_function(Function& lambda)                    //函数名to_function,传入参数lambda
    {
        return typename function_traits<Function>::function(lambda);    //将lambda传入function_traits<Function>::function 
    }
    
    //functional里面有定义了个std::plus。如果把plus定义为global的,访问时在global查找定义就会和std::plus冲突,产生二义。
    //auto plus = [](int a, int b) { std::cout << a + b << std::endl; };            //error,Plus不明确
    std::function<void(int, int)> plus = [](int a, int b) { std::cout << a + b << std::endl; };
    
    int main(int argc, char *argv[]) {
        //这是简单的lambda,其中包含琐碎的计算:
        //auto plus = [](int a, int b) { cout << a + b << endl; };
    
        //lambda和 std :: function 无法完成转换
        //auto loggedPlus = wrapLog(plus);                                                //test1
    
        //强制转换,OK,该行可以编译,但是很难看
        auto loggedPlus  = wrapLog(static_cast<std::function<void(int, int)>>(plus));   //test2
        loggedPlus(2, 3);
    
        //暂时最佳解决方案
        auto loggedPluss = wrapLog(to_function(plus));            //通过调用to_function函数 将 lambda表达式plus 转换为std::function<void(Args...)> 形式
        loggedPluss(2, 3);
    
        return 0;
    }
    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 10 元积分
        全部回答
    • 0
    • 只╰の濧尒堔僾 普通会员 1楼

      在C++中,lambda表达式和std::function可以互相转换,但这并不是强制转换。也就是说,如果lambda表达式被赋值给一个std::function类型,那么std::function会被自动转换为lambda表达式。

      例如:

      cpp std::function<int(int)> func = []{ return 10; }; std::lambda<int>(func);

      在上面的例子中,我们创建了一个std::function类型,然后使用lambda表达式将其赋值给这个类型。当我们尝试调用这个lambda表达式时,它实际上会被转换为std::function类型。

      注意,这个转换是自动的,不需要用户进行任何操作。如果lambda表达式无法转换为std::function类型,那么std::function类型就不会被赋值给lambda表达式。

      在C++11中,lambda表达式可以被转换为std::function类型,这是通过使用std::function陷阱来实现的。如果lambda表达式不能被转换为std::function类型,那么std::function陷阱就会被抛出。

      ```cpp

      include

      include

      std::function func = []{ return 10; }; std::function陷阱(func); ```

      在上面的例子中,我们使用std::function陷阱来尝试将lambda表达式转换为std::function类型。但是,由于lambda表达式不能被转换为std::function类型,std::function陷阱就会被抛出。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部