Учитывая следующий пример кода с любопытным повторяющимся шаблоном (CRTP):
template<typename X>
struct Base {
X f() const { return X{}; }
};
template<template<typename> typename T>
struct Derived : T<Derived<T>>
{};
const Derived<Base> d0{};
const Derived<Base> d1 = d0.f();
Я начал задаваться вопросом, можно ли с помощью концепций ограничить возможный набор базовых классов. Моя идея, основанная на этом ответе, предполагает использование requires B<T, Derived<T>>
, где B
определяется следующим образом:
#include <concepts>
// ...
template<template<typename> typename T, typename X>
concept B = requires (T<X> t)
{
{ t.f() } -> std::convertible_to<X>;
};
Очевидно, я не могу использовать эту форму:
template<template<typename> typename T> requires B<T, Derived<T>>
struct Derived : T<Derived<T>>
{};
потому что Derived
в require-clause еще не определен. Этот:
template<template<typename> typename T>
struct Derived requires B<T, Derived<T>> : T<Derived<T>>
{};
и это:
template<template<typename> typename T>
struct Derived : T<Derived<T>> requires B<T, Derived<T>>
{};
тоже не решайте проблему.
Есть ли способ преодолеть эти трудности и объединить концепции с CRTP?
(Я проводил тесты на GCC 10.0.1.)
Derived
способом CRTP), то возможный базовый класс CRTP должен использовать тип производного класса final, а не промежуточный тип. - person Nicol Bolas   schedule 15.06.2020Derived
является промежуточным классом, который ничего не знает о том, что делает базовый класс CRTP, он должен принимать что угодно. И еслиDerived
знает, что делает базовый класс CRTP ... тогда он либо знает, какой класс (шаблон) он использует, либо имеет некоторое представление об интерфейсе для этого шаблона. И этот интерфейс будет концепцией, определяющей базовый класс CRTP, а не производный. - person Nicol Bolas   schedule 15.06.2020Derived
. 3. Я хочу явно определить понятие как слой абстракции между классами. - person user11810469   schedule 15.06.2020Derived
принимает шаблон, а не класс. И ваш код создает экземпляр этого шаблона с определенным типом begin. Вы не можете ограничить шаблон на основе чего-то, чего еще не существует. - person Nicol Bolas   schedule 15.06.2020