qiubit
qiubit

Reputation: 4816

C++ - Recursive structure - is it possible?

I'm trying to implement a recursive structure in C++, something that should look kinda like this:

typedef struct {
    static constexpr int foo() {
        return 1;
    }
    typedef struct {
        // not valid - I meant foo() from "type" not from "recursive_type"
        static constexpr int foo() {
            return 2 * foo(); 
        }
        // ? (there should be another recursive type here)
    } recursive_type;
} type;

and that should work like this:

static_assert(type::foo() == 1, "Nope");
static_assert(type::recursive_type::foo() == 2, "Nope");
static_assert(type::recursive_type::recursive_type::foo() == 4, "Nope");

Basically - I want recursive_type to contain structure that looks exactly like type, but its foo() returns twice the value of type's foo(). But as I have pointed in the comments, there are a couple of problems with my approach and sadly it doesn't work.

Can such a structure be declared somehow in C++, or maybe it is not possible?

Upvotes: 1

Views: 235

Answers (2)

skyking
skyking

Reputation: 14360

Yes, borrowing from Let_Me_Be you can get the behavior you're asking for:

template< int tag >
struct X
 {
    static constexpr int foo() { return 2 * X<tag-1>::foo(); }

     typedef X<tag+1> recursive_type;
};


template< >
struct X<0>
{
    static constexpr int foo() { return 1; }

    typedef X<1> recursive_type;
};

typedef X<0> type;

static_assert(type::foo() == 1, "Nope");
static_assert(type::recursive_type::foo() == 2, "Nope");
static_assert(type::recursive_type::recursive_type::foo() == 4, "Nope");

Of course with the bonus that you could write deep recursive uses of recursive_type as X<n> instead...

Upvotes: 3

Šimon T&#243;th
Šimon T&#243;th

Reputation: 36433

Sort of. This is the way you implement type recursion in C++.

template< int tag >
struct X
{
    static constexpr int foo() { return 2 * X<tag-1>::foo(); }
};

template< >
struct X<1>
{
    static constexpr int foo() { return 1; }
};

#include <iostream>
using namespace std;

int main()
{
    static_assert(X<1>::foo() == 1, "Nope");
    static_assert(X<2>::foo() == 2, "Nope");
    static_assert(X<3>::foo() == 4, "Nope");

    cout << X<10>::foo() << endl;
}

Upvotes: 5

Related Questions