C++ 如何优雅地检查模板类型是否派生自C+中的特定基类+;11?
我有一个模板类C++ 如何优雅地检查模板类型是否派生自C+中的特定基类+;11?,c++,c++11,templates,C++,C++11,Templates,我有一个模板类Context。我想限制用户使用从特定类派生的指定类型(Stratege1,而不是Stratege2) class Base { public: virtual void run() = 0; }; class Stratege1 : public Base { public: virtual void run() { printf("Stratege1 \n"); } }; class Stratege2 { public:
Context
。我想限制用户使用从特定类派生的指定类型(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;
};
类基{
公众:
虚空运行()=0;
};
阶级战略1:公共基础{
公众:
虚拟空运行(){
printf(“策略1\n”);
}
};
阶级战略2{
公众:
虚拟空运行(){
printf(“策略2\n”);
}
};
模板类上下文{
公众:
无效运行(){
t、 run();
};
私人:
T;
};
如果用户希望这样调用,则可以:
Context<Stratege1> context;
context.run();
语境;
context.run();
但是,我不希望用户使用(以避免意外的潜在运行时问题)
语境;
context.run();
因为Stratege2
不是从Base
类派生的。在编译过程中有没有优雅的方法来限制这个概念
谢谢你的建议 使用(相当于std::enable_if::type
)和
#包括
模板
类上下文{
公众:
无效运行(){
t、 run();
};
私人:
T;
};
自C++11以来,您可以执行一些操作,这意味着在编译时检查失败时会出现一个不错的编译错误:
#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;
};
#include//is#u base#u of
模板
类上下文{
static_assert(std::是::value的_base_),
“T必须是上下文中基类的派生类。”);
公众:
无效运行(){
t、 run();
};
私人:
T;
};
例如:
Context<NotBase> c2;
Context;
错误:静态_断言失败“T必须是上下文中基类的派生类。”
->static_assert(std::是::value的_base_),
注意:在这里请求的模板类“Context”的实例化中
->语境c2;
在编译过程中有没有优雅的方法来限制这个概念
另一种可能的解决方案是通过部分专门化:第二个模板参数是true
,前提是T
是从base派生的
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(); };
};
接受从类基派生的任何类。否则,将拒绝该类。它不限于已知的类型。它只是要求用户按照指定实现模板参数的限制(例如,仅从类基派生)。
static_assert(std::is_Base_of::value,”);
如果要使用的方法是虚拟的,为什么不编写一个简单的非模板函数来处理基类指针呢?这是一个优雅的实现,但不容易理解:-)我不喜欢编译失败的替换错误消息。例如,根据您的建议:错误:在“struct std::enable_if”
中没有名为“type”的类型。不太明显。这是另一个优雅的实现,非常感谢:-)
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;
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<Stratege2, true> cs2; // compile