如何告诉模板参数是从某个类派生的

时间:2014-08-12 13:07:52

标签: c++ templates

现在,我正在编写基于特征的方法的程序。除了裸骨架之外的每个功能都是自己的包,派生自一个要素类。

我有以下标题定义:

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;。

1 个答案:

答案 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>;