懒惰依赖性类型(CRTP)

Lazy-evaluate dependent-types (CRTP)

本文关键字:CRTP 类型 依赖性      更新时间:2023-10-16

我希望以下代码工作:

template <typename Self>
struct foo_base {
    auto get(typename Self::type n) { return n; }
};
template <typename T>
struct foo : public foo_base<foo<T>> {
    using type = T;
};

当然,问题是首先实例化基础,因此您不能参考派生的成员类型。我在这里需要某种懒惰的评估。

我尝试制作功能模板并在其上有sfinae,类似于:

template <typename Self>
struct foo_base {
    template <typename T, typename = std::enable_if_t<std::is_same_v<T, typename Self::type>>>
    auto get(T n) { return n; }
};

,但似乎不会影响顺序。有什么想法吗?

编辑:

解决方案的约束:

  • 我无法将类型传递为来自派生类的模板参数。主要原因是:类型非常复杂,有几个一百个字符。所以不能做诸如struct foo : foo_base<foo<T>, T>或变体之类的事情。
  • 我需要将功能限制为该类型,我无法在功能内部检查。也许在派生的班级。

您可能会创建外部特征,例如:

template <template T>
struct TypeT;
template <typename Self>
struct foo_base {
    auto get(typename TypeT<Self>::type n) { return n; }
};
template <typename T> struct foo;
template <template T>
struct TypeT<foo<T>> {
    using type = T; // Don't use foo<T>::type, so traits can be used with incomplete type
};
template <typename T>
struct foo : public foo_base<foo<T>> {
    using type = typename TypeT<foo>::type; // Or directly = T
};

否则您确实可以使用Sfinae,但是您必须等待类型完成(实例化方法在您的情况下有效),例如:

template <typename Self>
struct foo_base
{
    template <typename T = Self>
    auto get(typename T::type n) { return n; }
};