惰性评估依赖类型(CRTP)

Pet*_*efi 7 c++ crtp c++17

我希望以下代码能够工作:

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;
};
Run Code Online (Sandbox Code Playgroud)

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

我已经尝试制作功能模板并在其上安装了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; }
};
Run Code Online (Sandbox Code Playgroud)

但它似乎不会影响订单.有任何想法吗?

编辑:

解决方案的限制:

  • 我无法从派生类传递类型作为模板参数.主要原因是:构造类型很复杂,有几百个字符.所以不能做类似的事情struct foo : foo_base<foo<T>, T>或变种.
  • 我需要将函数约束到该类型,我无法检查函数内部.也许派生类中存在重载.

Jar*_*d42 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
};
Run Code Online (Sandbox Code Playgroud)

否则,您可能确实使用 SFINAE,但您必须等待类型完成(在您的情况下实例化该方法时),例如:

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