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

时间:2014-06-24 08:52:22

标签: c++ visual-studio-2012 c++11

我正在修补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更改为容器中的Wrapper(也避免了宏魔法)

注意:由于我正在使用VS 2012,其中可变参数模板参数尚未实现,因此标准MS std::function使用了_VARIADIC_EXPAND_P1_1(_CLASS_FUNC_CLASS_1, , , , )之类的宏魔术来提供operator() 1}}

1 个答案:

答案 0 :(得分:2)

您尝试进行两次用户定义的转换,而这在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);
    }
}