如何优雅地检查模板类型是否来自C 11中的特定基类
How to elegantly check if the template type is derived from the specific base class in C++11?
我有一个模板类Context
。我想限制用户使用从特定类Base
派生的指定类型(Stratege1
,而不是Stratege2
(。
class Base {
public:
virtual void run() = 0;
};
class Stratege1 : public Base {
public:
virtual void run() {
printf("Stratege1 n");
}
};
class Stratege2 {
public:
virtual void run() {
printf("Stratege2 n");
}
};
template <typename T> class Context {
public:
void run() {
t.run();
};
private:
T t;
};
如果用户想这样调用,则可以:
Context<Stratege1> context;
context.run();
但是,我不希望用户使用(避免出乎意料的潜在运行时问题(
Context<Stratege2> context;
context.run();
因为Stratege2
不是从Base
类得出的。是否有任何优雅的方法可以限制编译期间的概念?
感谢您的建议。
自C 11以来,您可以static_assert
某物,这意味着当编译时检查失败时会出现一个不错的编译错误:
#include <type_traits> // is_base_of
template <typename T>
class Context {
static_assert(std::is_base_of<Base, T>::value,
"T must be a derived class of Base in Context<T>.");
public:
void run() {
t.run();
};
private:
T t;
};
例如:
Context<NotBase> c2;
error: static_assert failed "T must be a derived class of Base in Context<T>." -> static_assert(std::is_base_of<Base, T>::value, note: in instantiation of template class 'Context<NotBase>' requested here -> Context<NotBase> c2;
完整程序演示
使用std::enable_if_t
(相当于std::enable_if<B,T>::type
(和std::is_base_of
。
#include <type_traits>
template <typename T,
typename = std::enable_if_t<std::is_base_of<Base, T>::value> >
class Context {
public:
void run() {
t.run();
};
private:
T t;
};
是否有任何优雅的方式来限制编译期间的概念?
另一个可能的解决方案是通过部分专业化:仅当T
从base
true
template <typename T, bool = std::is_base_of<Base, T>::value>
class Context;
template <typename T>
class Context<T, true>
{
private:
T t;
public:
void run () { t.run(); };
};
所以你有
Context<Stratege1> cs1; // compile
// Context<Stratege2> cs2; // compilation error
不幸的是,您可以劫持Context
阐明第二个参数
Context<Stratege2, true> cs2; // compile
相关文章:
- 对派生自同一基类的类实现冲突检查
- 检查该类在编译时C++中是否有任何基类
- 如何在void*指针下检查运行时类型(允许简单类型,没有基类)?
- 检查实现哪些基类
- 什么更有效率?在重载函数中或通过在基类函数中检查对象类型来实现
- 如何优雅地检查模板类型是否来自C 11中的特定基类
- 模板 - 检查 T 是否继承自 A<Q>,其中 Q 是 T 的基类
- 类型特征检查 CRTP 派生,在基类中,问题是未定义的类型
- 通过基类指针检查模板类是否相等
- 当基类指针传递参数时,检查孩子的类型
- 如何检查对象是否是基类类型
- 如何使用Gmock检查基类功能
- 检查基类中派生模板类的相等性
- 在基类中提供检查实例类型是一种好的做法吗
- 将泛型子类上的检查条件分派到只知道基类的上下文中
- CRTP-从基类中检查派生类是否满足要求
- 如何使用static_assert检查派生类是否覆盖非虚拟基类方法
- 是否可以检查是否为类定义了成员函数,即使该成员继承自未知基类
- 根据派生中的值检查基类的模板参数
- 编译时检查基类是否为"接口"