我正在修补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}}
答案 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);
}
}