递归typedef函数定义:std::函数返回自己的类型
Recursive typedef function definition : std::function returning its own type
我正在尝试实现一个状态机。状态由类型为callback_t
:callback_t(int&)
的函数表示,该函数返回相同类型的函数。
我不知道如何实现它,因为递归类型函数似乎是不允许的。
以下是我尝试过的(作为玩具(:
#include <stdio.h>
#include <functional>
typedef std::function< callback_t(int &) > callback_t ;
callback_t f1(int & i)
{
i++;
return f1;
}
callback_t f0(int & i)
{
if(i==0) i++;
return f1;
}
callback_t start(int & i)
{
i=0;
return f0;
}
int main(int argc, char **argv)
{
callback_t begin = start;
int i=0;
while(i<100)
begin = begin(i);
printf("hello worldn");
return 0;
}
错误:
C:/work/tests/tests/main.cpp:4:41: error: 'callback_t' was not declared in this scope
typedef std::function< callback_t(int &) > callback_t ;
^
有没有办法实施这种行为?
环境:win7,codelite,mingw 4.8.1
由于递归类型定义是不可能的,您可以声明一个携带函数并隐式转换为它的结构:
template< typename... T >
struct RecursiveHelper
{
typedef std::function< RecursiveHelper(T...) > type;
RecursiveHelper( type f ) : func(f) {}
operator type () { return func; }
type func;
};
typedef RecursiveHelper<int&>::type callback_t;
示例:http://coliru.stacked-crooked.com/a/c6d6c29f1718e121
用一种类型替换另一种类型的小库:
template<class T>struct tag{using type=T;};
template<class X, class A, class B> struct subst:tag<X>{};
template<class X, class A, class B>
using subst_t=typename subst<X,A,B>::type;
template<class A, class B> struct subst<A,A,B>:tag<B>{};
template<class X, class A, class B>
struct subst<X&,A,B>:tag<subst_t<X,A,B>&>{};
template<class X, class A, class B>
struct subst<X&&,A,B>:tag<subst_t<X,A,B>&&>{};
template<class X, class A, class B>
struct subst<X const,A,B>:tag<subst_t<X,A,B>const>{};
template<class X, class A, class B>
struct subst<X volatile,A,B>:tag<subst_t<X,A,B>volatile>{};
template<class X, class A, class B>
struct subst<X const volatile,A,B>:tag<subst_t<X,A,B>const volatile>{};
template<template<class...>class Z,class...Xs, class A, class B>
struct subst<Z<Xs...>,A,B>:tag<Z<subst_t<Xs,A,B>...>>{};
template<template<class,size_t>class Z,class X,size_t n, class A, class B>
struct subst<Z<X,n>,A,B>:tag<Z<subst_t<X,A,B>,n>>{};
template<class R,class...Xs, class A, class B>
struct subst<R(Xs...),A,B>:tag<subst_t<R,A,B>(subst_t<Xs,A,B>...)>{};
现在我们使用它:
struct own_type {};
template<class Sig>
struct recursive_func{
using func=std::function< subst_t<Sig, own_type, recursive_func> >;
template<class...Ts>
std::result_of_t<func const&(Ts...)>
operator()(Ts&&...ts)const{
return f(std::forward<Ts>(ts)...);
}
operator func const&()const&{return f;}
operator func&()&{return f;}
operator func()&&{return std::move(f);}
template<class F,
class=std::enable_if_t<
!std::is_same<recursive_func,std::decay_t<F>>::value
&& std::is_convertible<F,func>::value
>
>
recursive_func(F&&fin):f(fin){}
func* operator->(){return f;}
func const* operator->()const{return f;}
private:
func f;
};
它给了你一个可爱的语法:
recursive_func< std::vector<own_type>() > f;
是一个返回自己类型的向量的函数。
这使用了少量的C++14 _t
别名。如果您的编译器严格来说是C++11,那么std::blah_t<?>
可以用typename std::blah<?>::type
代替。可能还有其他拼写错误。
一个弱点是,当馈送own_type
时,期望其类型在直接上下文中满足某些属性的模板可能会失败。这可以通过subst
理解的延迟模板应用程序来解决,但在随意使用时不太可能成为问题。
实例
typedef std::function< callback_t(int &) > callback_t ;
**********
您尝试用定义本身定义一个新类型。这是不可能的!在定义callback_t之前,不能使用它。
相关文章:
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- 是否可以在不填充自己的参数的情况下将模板函数作为参数传递?
- 在C++中,我可以在定义自己的复制构造函数后跳过定义赋值运算符吗?
- 在类自己的成员函数中构造类时,如何强制类模板参数推导?
- 在这种情况下,工会成员会调用自己的析构函数吗
- 您自己的类型的结构化绑定,不是结构或元组(通过公共成员函数)
- 我正在尝试在视觉工作室上创建自己的库/源函数
- 将自己的函数添加到 ifstream
- 在函数调用时C++多组参数及其自己的括号?
- 如何解决对自己的C++成员函数的未定义引用?
- C :基类调用自己的虚拟函数 - 一个反图案
- 自己的C++列表类实现(插入函数)出现问题
- 函数可以将指针返回其自己的类型
- 类中的枚举在调用自己的函数时不会改变
- GCC 或 Clang 关于函数参数在其自己的默认参数中的范围内的名称是否正确?
- 如何自己为我自己的shared_ptr实现实现别名构造函数
- 如何在我自己的类 Vector 中使用 Move 构造函数而不是 Move 赋值运算符
- G++ 切换为不包含自己的符号函数名称(和调试数据)-
- 在构造函数(C )中填写我自己的向量类
- 如何在 C++ 中从类成员函数自己的定义递归调用该函数