从碱基调用访问派生的 crtp class 的函数
Accessing functions of a derived crtp class from the base calls
我需要能够从基础 CRTP class 中访问派生 class 的静态方法。有什么方法可以实现吗?
示例代码如下:
#define REQUIRES(...) std::enable_if_t<(__VA_ARGS__), bool> = true
template<typename Derived>
struct ExpressionBase {
Derived& derived() { return static_cast<Derived&>(*this); }
const Derived& derived() const { return static_cast<const Derived&>(*this); }
constexpr static int size()
{
return Derived::size();
}
template<typename T, REQUIRES(size() == 1)>
operator T() const;
};
struct Derived : public ExpressionBase<Derived>
{
constexpr static int size()
{
return 1;
}
};
从ExpressionBase<Derived>
派生涉及ExpressionBase<Derived>
的实例化,因此涉及实体
的声明
template<typename T, REQUIRES(size() == 1)>
operator T() const;
这里,std::enable_if_t
得到了一个格式错误的模板参数(因为 Derived
还没有完成)。 SFINAE 规则在这里不适用,因为格式错误的表达式不在模板参数类型的直接上下文中,因此它被视为硬错误。
为了使错误构造在即时上下文中发生,请使用以下代码:
#include <type_traits>
template <bool B, class T>
struct lazy_enable_if_c {
typedef typename T::type type;
};
template <class T>
struct lazy_enable_if_c<false, T> {};
template <class Cond, class T>
struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
template <class T>
struct type_wrapper {
using type = T;
};
#define REQUIRES(...) std::enable_if_t<(__VA_ARGS__), bool> = true
template<typename Derived>
struct ExpressionBase {
Derived& derived() { return static_cast<Derived&>(*this); }
const Derived& derived() const { return static_cast<const Derived&>(*this); }
struct MyCond {
static constexpr bool value = Derived::size() == 1;
};
template<typename T, typename = typename lazy_enable_if<MyCond, type_wrapper<T>>::type>
operator T () const {
return T{};
}
};
struct Derived : public ExpressionBase<Derived>
{
constexpr static int size() {
return 1;
}
};
int main() {
Derived d;
int i = d;
return 0;
}
它实际上改编自 boost
,您可以在其中找到更多详细信息 here。
我需要能够从基础 CRTP class 中访问派生 class 的静态方法。有什么方法可以实现吗?
示例代码如下:
#define REQUIRES(...) std::enable_if_t<(__VA_ARGS__), bool> = true
template<typename Derived>
struct ExpressionBase {
Derived& derived() { return static_cast<Derived&>(*this); }
const Derived& derived() const { return static_cast<const Derived&>(*this); }
constexpr static int size()
{
return Derived::size();
}
template<typename T, REQUIRES(size() == 1)>
operator T() const;
};
struct Derived : public ExpressionBase<Derived>
{
constexpr static int size()
{
return 1;
}
};
从ExpressionBase<Derived>
派生涉及ExpressionBase<Derived>
的实例化,因此涉及实体
template<typename T, REQUIRES(size() == 1)>
operator T() const;
这里,std::enable_if_t
得到了一个格式错误的模板参数(因为 Derived
还没有完成)。 SFINAE 规则在这里不适用,因为格式错误的表达式不在模板参数类型的直接上下文中,因此它被视为硬错误。
为了使错误构造在即时上下文中发生,请使用以下代码:
#include <type_traits>
template <bool B, class T>
struct lazy_enable_if_c {
typedef typename T::type type;
};
template <class T>
struct lazy_enable_if_c<false, T> {};
template <class Cond, class T>
struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
template <class T>
struct type_wrapper {
using type = T;
};
#define REQUIRES(...) std::enable_if_t<(__VA_ARGS__), bool> = true
template<typename Derived>
struct ExpressionBase {
Derived& derived() { return static_cast<Derived&>(*this); }
const Derived& derived() const { return static_cast<const Derived&>(*this); }
struct MyCond {
static constexpr bool value = Derived::size() == 1;
};
template<typename T, typename = typename lazy_enable_if<MyCond, type_wrapper<T>>::type>
operator T () const {
return T{};
}
};
struct Derived : public ExpressionBase<Derived>
{
constexpr static int size() {
return 1;
}
};
int main() {
Derived d;
int i = d;
return 0;
}
它实际上改编自 boost
,您可以在其中找到更多详细信息 here。