现在,我正在编写基于特征的方法的程序。除了裸骨架之外的每个功能都是自己的包,派生自一个要素类。
我有以下标题定义:
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
{
...
}
当我现在尝试在addChildFeature()
的实例上调用FeatureClass
方法时
编译器在哭,因为addChildFeat()
方法只看到MyChildFeatureInterface
,当然没有成员Parent
。
我可以通过直接从MyChildFeatureInterface
派生Feature
轻松绕过这个问题,但一方面我发现这是次优的,另一方面我想知道是否有办法告诉编译器:&#34;这个模板参数可以是任何类,但它必须来自X类和#34;。
答案 0 :(得分:2)
当然,您可以轻松地向编译器说一个类必须从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>;