是否可以重新路由lambda以将其包装在包装器类中

Is it possible to reroute lambda to wrap it in a wrapper class?

本文关键字:包装 lambda 新路由 路由 是否      更新时间:2023-10-16

我正在修补std::function的矢量:

#include "stdafx.h"
#include <stdexcept>
#include <functional>
#include <iostream>
#include <vector>
typedef std::function<void(int)> FuncType;
std::vector<FuncType> container;
int _tmain(int argc, _TCHAR* argv[])
{
    container.push_back([](int i){std::cout << i+1 << std::endl;});
    container.push_back([](int i){std::cout << i+42 << std::endl;});
    for(auto & o : container)
    {
        o(4);
    }
    return 0;
}

基本上只是返回5和46,并在考虑是否可以将容器的声明更改为某种包装器类,但要保持lambdas的推回(=不改变除声明外的任何其他内容)。

目前我试图实现一些存根包装不做什么特别应该只是编译,但似乎从lambda到wrapper的转换不能隐式完成。

#include "stdafx.h"
#include <stdexcept>
#include <functional>
#include <iostream>
#include <vector>

typedef std::function<void(int)> FuncType;
template<class T>
class Wrapper
{
public:
    Wrapper(T t)
    {
        _t = t;
    }
   void operator()(int i) const
   {
       _t(i);
   }
protected:
   T & _t;
};

std::vector<Wrapper<FuncType>> container; // Only line changed
int _tmain(int argc, _TCHAR* argv[])
{
    container.push_back([](int i){std::cout << i+1 << std::endl;});
    container.push_back([](int i){std::cout << i+42 << std::endl;});
    for(auto & o : container)
    {
        o(4);
    }
    return 0;
}

这里的目标是包装对o(int)的调用并输出一些诊断,例如:o.target_type().name()或性能值等,但没有改变push_back到容器包装(避免宏魔术)

注意:由于我使用的是VS 2012,可变模板参数尚未实现,标准MS std::function采用了一些宏魔术,如_VARIADIC_EXPAND_P1_1(_CLASS_FUNC_CLASS_1, , , , )来提供operator()

您正在尝试进行两个用户定义的转换,这在c++中是非法的。相反,让构造函数成为一个受约束的模板。见下文:

#include <functional>
#include <utility>
#include <iostream>
#include <vector>
#include <type_traits>
typedef std::function<void(int)> FuncType;
template<class T>
class Wrapper
{
public:
    template<typename U,
    typename std::enable_if<
        std::is_constructible<T, U>::value,
        int
    >::type = 0>
    Wrapper(U t)
      : _t(std::move(t))
    {}
   void operator()(int i) const
   {
       _t(i);
   }
private:
   T _t;
};
std::vector<Wrapper<FuncType>> container; // Only line changed
int main(int argc, char* argv[])
{
    container.push_back([](int i){std::cout << i+1 << std::endl;});
    container.push_back([](int i){std::cout << i+42 << std::endl;});
    for(auto & o : container)
    {
    o(4);
    }
}