延迟评估依赖类型 (CRTP)
Lazy-evaluate dependent-types (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; }
};
不过好像不影响顺序。有什么想法吗?
编辑:
解的约束条件:
- 我无法从派生 class 将类型作为模板参数传递。
主要原因是:类型构造起来很复杂,有几个
百个字符。所以不能做类似
struct foo : foo_base<foo<T>, T>
或变体的事情。
- 我需要将函数限制为该类型,我
无法检查函数内部。也许有超载
派生 class.
您可以创建外部特征,例如:
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; }
};
我希望以下代码能够工作:
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; }
};
不过好像不影响顺序。有什么想法吗?
编辑:
解的约束条件:
- 我无法从派生 class 将类型作为模板参数传递。
主要原因是:类型构造起来很复杂,有几个
百个字符。所以不能做类似
struct foo : foo_base<foo<T>, T>
或变体的事情。 - 我需要将函数限制为该类型,我 无法检查函数内部。也许有超载 派生 class.
您可以创建外部特征,例如:
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; }
};