Рекурсивно определенные вложенные типы (в терминах неполных типов)

Откуда берется рекурсия в определении cycle перерыв?

#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;
}

К моему удивлению, приведенный выше код компилируется. Является ли это допустимым фрагментом кода, и если да, что означает (краткое описание) типа cycle?

1 ответ

Решение

struct X : Recursive<X> пример шаблона любопытно повторяющегося шаблона, но бесконечной рекурсии не происходит, если вы не обращаетесь к вложенному cycle тип. Например decltype(x)::cycle имеет другой тип, чем 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;
}

Это печатает

Recursive<int>

Recursive<int>::X

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

Таким образом, отречение будет продолжаться вечно, но только если вы явно получите доступ к следующему вложенному cycle тип.

Другие вопросы по тегам