この型をC++で定義できますか？


以下はC#のコードです。  
C++でaと等価な型は定義できるでしょうか？

[code]

    using System;
    
    namespace ConsoleApp1
    {
        class Program
        {
            delegate a a();
    
            static void Main(string[] args)
            {
                a x = f;
                for (int i = 0; i < 10; ++i) x = x();
            }
            static a f() { Console.Write("f"); return g; }
            static a g() { Console.Write("g"); return f; }
        }
    }
    
[/code]

C++で関数ポインタを使い、実装したかなり近いコードが以下になりますが、  
キャストが必須で、可能ならばキャストをなくしたいです。

[code]

    #include <stdio.h>
    typedef void *(*a)();
    void *f();
    void *g();
        
    void *f() { puts("f"); return (void *)g; }
    void *g() { puts("g"); return (void *)f; }
    
    int main()
    {
        a x = f;
        for (int i = 0; i < 10; ++i)x = (a)x();
        return 0;
    }
    
[/code]

私はC++では完全にキャストなしのaを定義できないのではないか？と疑っています。  
aのポイントは関数の戻り値の型がその関数自身になっているところです。  
C++でリストのクラスを作るとき

[code]

    class Node
    {
    public:
        Item item;
        Node *nxt;
    };
    
[/code]

のような自分自身のポインタを定義に含めるような書き方をできると思うのですが、  
今回のaのような関数と戻り値の場合、そのような書き方が用意されていないように思えるのです。

今回の質問の元ネタは5chの「なあ、再帰関数好きな人いる？ パート3」というスレの>>676になります。  
<https://mevius.5ch.net/test/read.cgi/tech/1448704298/>




C/C++では自分自身と同じ型を返す関数ポインタ型を直接定義することはできないと思います。

別解として、暗黙の変換コンストラクタを持つ関数オブジェクトを定義すればキャストを省略できます。  
特に仮想関数や継承を使う必要はないです。

C++11以降では可変引数テンプレートを使うことで、一応アダプターの汎用化はできます。

[code]

    #include <cstdio>
    
    template<typename... TArgs> struct MyFuncWrapper {
        using FuncPtr = MyFuncWrapper(*)(TArgs...);
        FuncPtr m_func;
        MyFuncWrapper() = delete;
        // 暗黙の変換コンストラクタ。
        MyFuncWrapper(FuncPtr p) : m_func(p) {
        }
        MyFuncWrapper operator()(TArgs... args) const {
            return m_func(args...);
        }
    };
    
    MyFuncWrapper<> f();
    MyFuncWrapper<> g();
    
    MyFuncWrapper<> f() { std::puts("f"); return g; }
    MyFuncWrapper<> g() { std::puts("g"); return f; }
    
    int main() {
        MyFuncWrapper<> x = f;
        for (int i = 0; i < 10; ++i) {
            x = x();
        }
        return 0;
    }
    
[/code]




C/C++では自分自身と同じ型を返す関数ポインタ型を直接定義することはできないと思います。

別解として、暗黙の変換コンストラクタを持つ関数オブジェクトを定義すればキャストを省略できます。  
特に仮想関数や継承を使う必要はないです。

C++11以降では可変引数テンプレートを使うことで、一応アダプターの汎用化はできます。

[code]

    #include <cstdio>
    
    template<typename... TArgs> struct MyFuncWrapper {
        using FuncPtr = MyFuncWrapper(*)(TArgs...);
        FuncPtr m_func;
        MyFuncWrapper() = delete;
        // 暗黙の変換コンストラクタ。
        MyFuncWrapper(FuncPtr p) : m_func(p) {
        }
        MyFuncWrapper operator()(TArgs... args) const {
            return m_func(args...);
        }
    };
    
    MyFuncWrapper<> f();
    MyFuncWrapper<> g();
    
    MyFuncWrapper<> f() { std::puts("f"); return g; }
    MyFuncWrapper<> g() { std::puts("g"); return f; }
    
    int main() {
        MyFuncWrapper<> x = f;
        for (int i = 0; i < 10; ++i) {
            x = x();
        }
        return 0;
    }
    
[/code]

