Nikos Athanasiou
Nikos Athanasiou

Reputation: 31519

Recursively defined nested types (in terms of incomplete types)

Where does the recursion in the definition of cycle break ?

#include <iostream>
using namespace std;

template<typename T>
struct Recursive
{
    using cycle = struct X : Recursive<X> {}; // would work for Recursive<T> as well
};

int main() 
{
    Recursive<int> x;
    return 0;
}

To my surprise the above code compiles - Is it a valid piece of code and if yes what's the meaning (a brief description) of the type cycle ?

Upvotes: 3

Views: 660

Answers (1)

TemplateRex
TemplateRex

Reputation: 70526

The struct X : Recursive<X> is an example of the Curiously Recurring Template Pattern, but there is no infinite recursion taking place unless you access the nested cycle type. E.g. decltype(x)::cycle is of a different type than decltype(x)::cycle::cycle.

#include <iostream>
#include <type_traits>
#include <typeinfo>
#include <cxxabi.h>

using namespace std;

template<typename T>
struct Recursive
{
    using cycle = struct X : Recursive<X> {};
};


int main() 
{
    int status;
    Recursive<int> x;
    std::cout << abi::__cxa_demangle(typeid(x).name(), 0, 0, &status) << '\n';
    std::cout << abi::__cxa_demangle(typeid(decltype(x)::cycle).name(), 0, 0, &status) << '\n';
    std::cout << abi::__cxa_demangle(typeid(decltype(x)::cycle::cycle).name(), 0, 0, &status) << '\n';
    return 0;
}

This prints

Recursive<int>

Recursive<int>::X

Recursive<Recursive<int>::X>::X

So the recusion will go on forever, but only if you explicitly access a further nested cycle type.

Upvotes: 5

Related Questions