1

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?

3
  • You'll better use pointers, perhaps smart ones. And avoid naming two struct (in the same translation unit) with the same name. Commented Dec 2, 2015 at 13:25
  • Yeah, I know I could use pointers to do that, but I need an object whose semantics look like the ones I described. (So recursive_type should spawn slightly modified version of the object it is called on) Commented Dec 2, 2015 at 13:27
  • Did you consider switching to Ocaml. It has recursive functors... Commented Dec 2, 2015 at 13:29

2 Answers 2

5

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; } 
Sign up to request clarification or add additional context in comments.

Comments

3

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...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.