我有一个函数应该返回与该函数相同类型的std :: function。基本上我想这样的事情:返回std :: function函数的返回类型
using RetType = std::function<RetType(void)>;
显然不会编译。我如何正确地声明返回类型?
我有一个函数应该返回与该函数相同类型的std :: function。基本上我想这样的事情:返回std :: function函数的返回类型
using RetType = std::function<RetType(void)>;
显然不会编译。我如何正确地声明返回类型?
你不能这样使用std::function
。
你可以推出自己的,但它会需要一些工作。
这里是一个草图:
template<class T, class A, class B>
struct sub{using type=T;};
template<class T, class A, class B>
using sub_t=typename sub<T,A,B>::type;
template<class T, class B>
struct sub<T,T,B>{using type=B;};
template<class R,class...Args,class A,class B>
struct sub<R(Args...),A,B>{
using type=sub_t<R,A,B>(sub_t<Args,A,B>...);
};
写以上。它需要一个类型T
,如果它匹配A
它返回B
。否则它返回T
。它也适用于功能签名。
我们可以在签名与“标志”类型时使用该函数对象本身的类型来代替:
struct recurse{}; // flag type
// not needed in C++14:
template<class Sig>
using result_of_t=typename std::result_of<Sig>::type;
template<class Sig>
struct func {
using Sig2=sub_t<Sig,recurse,func>;
using function = std::function<Sig2>;
function impl;
template<class...Ts>
result_of_t<function const&(Ts...)>
operator()(Ts&&...ts)const
{
return impl(std::forward<Ts>(ts)...);
}
};
然后func<recurse()>
是一个函数对象,调用它时,返回func<recurse()>
。
原来,实现和存储std::function<Sig2>
一样简单,然后调用它。上面的代码缺少打磨 - 你想要的构造,更多的运营商,隐私等
注意,如果你想避免捕捉到自己的副本的Y组合子可能是有用的通过引用来返回*this
在lambda中,因为通过引用捕获意味着有限的生命周期(并避免使用共享ptr)。
其他有用的工作是增强sub
以处理引用到A
甚至包含A
作为参数的模板。 (通用子算法在C++中不可行,因为C++没有完整的元模板功能,但是处理当前在std
中的每个模板类都很容易:它们都是纯粹的类型模板,或者是std::array
)。
为了完整起见,你可以添加这sub
:
// optional stuff for completeness:
template<class T,class A,class B>
struct sub<T&,A,B>{
using type=sub_t<T,A,B>&;
};
template<class T,class A,class B>
struct sub<T*,A,B>{
using type=sub_t<T,A,B>*;
};
template<template<class...>class Z,class... Ts,class A,class B>
struct sub<Z<Ts...>,A,B>{
using type=Z<sub_t<Ts,A,B>...>;
};
template<template<class,size_t>class Z,class T,size_t n,class A,class B>
struct sub<Z<T,n>,A,B>{
using type=Z<sub_t<T,A,B>,n>;
};
template<class T,size_t n,class A,class B>
struct sub<T[n],A,B>{
using type=sub_t<T,A,B>[n];
};
template<class T,class A,class B>
struct sub<T[],A,B>{
using type=sub_t<T,A,B>[];
};
template<class T,class A,class B>
struct sub<T const,A,B>{
using type=sub_t<T,A,B> const;
};
template<class T,class A,class B>
struct sub<T volatile const,A,B>{
using type=sub_t<T,A,B> volatile const;
};
template<class T,class A,class B>
struct sub<T volatile,A,B>{
using type=sub_t<T,A,B> volatile;
};
,现在可递归许多模板,阵列上,引用和指针,与CV-合格的类型。这允许你写类似:
func< std::vector<recurse>() >
这是一个函数对象,其operator()
返回func< std::vector<recurse>() >
。
请注意,此过程并不完美,好像some_template<recurse>
不是有效的模板实例化,上述操作将不起作用。一个陌生的版本,可能会应用模板和参数,在这种情况下,需要替换,然后是应用程序。
你有演示吗? – 2015-04-01 18:50:54
@KerrekSB我现在在做。 – Yakk 2015-04-01 19:43:44
是否使用'auto'工作? – dwcanillas 2015-04-01 18:09:38
@dwcanillas:喜欢[这个问题](http://stackoverflow.com/q/25338795/596781)? – 2015-04-01 18:10:17
恩,我不知道我明白在这种情况下我会如何使用汽车。我必须声明这个类型,然后自己定义这个函数。 – 2015-04-01 18:10:27