现在,我正在使用基于特征的方法编写程序。除了基本框架之外,每个功能都作为自己的包出现,派生自要素类。
我有以下 header 定义:
class Feature
{
public:
Feature(std::string Name)
: Parent(nullptr), Name(Name)
{
if (FeatureNames.count(Name) == 0)
FeatureNames.insert(Name);
else
throw std::logic_error(std::string("Feature: The Feature with the name '") + Name + "' already exists");
}
virtual ~Feature(){}
const std::string &getName(){ return Name; }
virtual void shutDown() = 0;
protected:
Feature *Parent;
private:
static std::set<std::string> FeatureNames;
std::string Name;
};
template<class ChildFeat>
class FeatureEx : public Feature
{
public:
FeatureEx(std::string Name) :Feature(Name){}
virtual ~FeatureEx(){}
void addChildFeature(ChildFeat *Child);
protected:
std::vector<ChildFeat*> Children;
};
//implementation
template<class ChildFeat>
void FeatureEx<ChildFeat>::addChildFeature(ChildFeat *child)
{
Children.push_back(child);
child->Parent = this;
}
我有一个 Feat-class 和一个 ChildFeat-Class,如下所示:
class FeatureClass : public FeatureEx<MyChildFeatureInterface>
{
...
}
class MyChildFeat : public Feature, public MyChildFeatureInterface
{
...
}
当我现在尝试在 FeatureClass
的实例上调用 addChildFeature()
方法时
编译器哭了,因为 addChildFeat()
方法只看到一个 MyChildFeatureInterface
,当然没有成员 Parent
。
我可以通过直接从 Feature
派生 MyChildFeatureInterface
轻松绕过这个问题,但一方面我发现这不是最优的,另一方面我想知道是否有一种方法可以告诉编译器:“这个模板参数可以是任何类,但它必须派生自类 X”。
最佳答案
当然,您可以轻松地告诉编译器一个类必须派生自 Base。
函数示例:
template<class X> auto my_function1(X&& x)
-> decltype(*declval<const volatile Base**>() = &x, declval<void>());
如果 x
不是 Base
的一种,所以不是从它派生的,赋值是错误的,因此函数在重载时从考虑中移除-解决步骤。
我喜欢这种形式,因为它可以立即转移到检查您可能需要的任何奇怪表达式。
或者像 Matthieu M. 一样正确地使用标准库中的预打包测试 mentions in a comment (仅在类里面工作):
template<class X> auto my_function2(X&& x)
-> enable_if_t<is_base_of<Base, typename decay<X>::type>::value, void>;
关于c++ - 如何告诉模板参数是从某个类派生的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25265127/