Разрешение порядка инициализации CRTP - PullRequest
3 голосов
/ 17 октября 2019

У меня есть некоторая зависимость от CRTP, которую я не знаю, как решить. В идеале я хочу поместить как можно больше вещей в базовый класс, например, функции, поэтому мне не нужно переопределять их для каждого класса, который их наследует. Похоже, это вызывает проблему с порядком инициализации, где result_type зависит от типа, который еще предстоит инициализировать. Вот пример: https://godbolt.org/z/YpfcPB

А вот код:

template<typename T>
struct CRTP_Derived;

template<typename Derived>
struct CRTP
{
    using result_type = typename Derived::result_type;

};

template<typename T>
struct CRTP_Derived : public CRTP<CRTP_Derived<T>>
{
    using result_type = T;
};

int main()
{
    CRTP_Derived<int> a;
    return 0;
}

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Я также использовал отдельный тип черт для подобных проблем. Вы можете немного уменьшить необходимый шаблон, если вы сделаете черты вторым параметром шаблона, вместо того, чтобы требовать от пользователей специализировать отдельный шаблон:

template<typename Derived, typename Traits>
struct CRTP
{
    using result_type = typename Traits::result_type;
};

template<typename T>
struct CRTP_Derived_Traits
{
    using result_type = T;
};

template<typename T>
struct CRTP_Derived : public CRTP<CRTP_Derived<T>, CRTP_Derived_Traits<T>>
{
};

int main()
{
    CRTP_Derived<int> a;
    return 0;
}
0 голосов
/ 17 октября 2019

Обходной путь, который я нашел, - это удаление typedef в отдельном классе, но я был бы рад увидеть другие решения. https://godbolt.org/z/a7NCE2

template<typename T>
struct CRTP_Derived;

template<typename Derived>
struct traits;

template<typename T>
struct traits<CRTP_Derived<T>>
{
    using result_type = T;
};

template<typename Derived>
struct CRTP
{
    using result_type = typename traits<Derived>::result_type;
};

template<typename T>
struct CRTP_Derived : public CRTP<CRTP_Derived<T>>
{
    using result_type = T;
};

int main()
{
    CRTP_Derived<int> a;
    return 0;
}
...