惰性评估依存类型(CRTP)

时间:2019-02-18 13:52:50

标签: c++ c++17 crtp

我想使用以下代码:

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>或变体的事情。
  • 我需要将函数限制为该类型,我 无法检查函数内部。也许在 派生类。

1 个答案:

答案 0 :(得分:4)

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

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