Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何为模板类参数指定所需的继承?_C++_Templates - Fatal编程技术网

C++ 如何为模板类参数指定所需的继承?

C++ 如何为模板类参数指定所需的继承?,c++,templates,C++,Templates,我有以下结构: class ElementEx { public: ElementEx() {} AddChild(ElementEx* element) { // some stuff } }; class A : ElementEx { public: A() {} }; class B : ElementEx { public: B() {} }; template <class T> class MyN

我有以下结构:

class ElementEx
{
public:
    ElementEx() {}
    AddChild(ElementEx* element) 
    {
        // some stuff
    }
};

class A : ElementEx
{
public:
    A() {}
};

class B : ElementEx
{
public:
    B() {}
};


template <class T>
class MyNewClass : public T
{
public:
    MyNewClass()
    {
        ElementEx* newElement = new ElementEx();
        AddChild(newElement);
    }
};

但是这看起来真的很不雅观(如果错误的类型作为T输入,那么很容易出错),我认为一定有更好的方法来做到这一点。

有几种方法可以很好地做到这一点,但它们都有使用1的基础。)静态断言。2) 静态评估函数

就个人而言,我会使用(在构造函数中)

static_断言(std::is_base_of::value,“T必须派生自ElementEx”)

但可能有更好的办法。问题的X部分是什么(你想用这种奇怪的继承结构实现什么?

有几种方法可以很好地做到这一点,但它们都有使用1.)静态断言的基础。2) 静态评估函数

就个人而言,我会使用(在构造函数中)

static_断言(std::is_base_of::value,“T必须派生自ElementEx”)

但可能有更好的办法。问题的X部分是什么(你试图用这种奇怪的继承结构实现什么?

只要你满足于父类支持
AddChild
接受
ElementEx
,你就可以使用正常的编译器错误轻松做到这一点

修复代码中的一系列错误后(a和B私有继承,所有类都有私有构造函数,
AddChild
没有返回类型)我可以通过将
this->
添加到
AddChild
的调用中使其正常工作,因为
AddChild
是一个依赖名称,您可以通过限定类型或添加
this->
向编译器指示该名称。如果您预计不需要对该方法进行虚拟调用,您可以交替调用
ElementEx::AddChild
,以强制执行正确的查找。修正代码如下

class ElementEx
{
public:
    ElementEx() {}
    void AddChild(ElementEx* element)
    {
        // some stuff
    }
};

class A : public ElementEx
{
public:
    A() {}
};

class B : public ElementEx
{
public:
    B() {}
};


template <class T>
class MyNewClass : public T
{
public:
    MyNewClass()
    {
        ElementEx* newElement = new ElementEx();
        this->AddChild(newElement);
    }
};

struct Bad {};

int main()
{
    MyNewClass<B> b;          // Compiles.
    MyNewClass<Bad> bad;      // error: 'class MyNewClass<Bad>' has no member named 'AddChild'
}
class-ElementEx
{
公众:
ElementEx(){}
void AddChild(ElementEx*元素)
{
//一些东西
}
};
A类:公共元素
{
公众:
A(){}
};
B类:公共元素
{
公众:
B(){}
};
模板
类MyNewClass:public T
{
公众:
MyNewClass()
{
ElementEx*newElement=newelementex();
此->添加子元素(新元素);
}
};
结构错误{};
int main()
{
MyNewClass b;//编译。
MyNewClass错误;//错误:“类MyNewClass”没有名为“AddChild”的成员
}

只要您满足于父类支持的
AddChild
接受
ElementEx
,就可以使用正常的编译器错误轻松地执行此操作

修复代码中的一系列错误后(a和B私有继承,所有类都有私有构造函数,
AddChild
没有返回类型)我可以通过将
this->
添加到
AddChild
的调用中使其正常工作,因为
AddChild
是一个依赖名称,您可以通过限定类型或添加
this->
向编译器指示该名称。如果您预计不需要对该方法进行虚拟调用,您可以交替调用
ElementEx::AddChild
,以强制执行正确的查找。修正代码如下

class ElementEx
{
public:
    ElementEx() {}
    void AddChild(ElementEx* element)
    {
        // some stuff
    }
};

class A : public ElementEx
{
public:
    A() {}
};

class B : public ElementEx
{
public:
    B() {}
};


template <class T>
class MyNewClass : public T
{
public:
    MyNewClass()
    {
        ElementEx* newElement = new ElementEx();
        this->AddChild(newElement);
    }
};

struct Bad {};

int main()
{
    MyNewClass<B> b;          // Compiles.
    MyNewClass<Bad> bad;      // error: 'class MyNewClass<Bad>' has no member named 'AddChild'
}
class-ElementEx
{
公众:
ElementEx(){}
void AddChild(ElementEx*元素)
{
//一些东西
}
};
A类:公共元素
{
公众:
A(){}
};
B类:公共元素
{
公众:
B(){}
};
模板
类MyNewClass:public T
{
公众:
MyNewClass()
{
ElementEx*newElement=newelementex();
此->添加子元素(新元素);
}
};
结构错误{};
int main()
{
MyNewClass b;//编译。
MyNewClass错误;//错误:“类MyNewClass”没有名为“AddChild”的成员
}

编译器在这里抱怨,因为它不知道
AddChild
在第一个过程中依赖于
t
AddChild
可以通过在调用前加上
this->
使其成为依赖名称,因此当
T
已知时,会将查找延迟到第二个过程。

编译器在这里抱怨,因为它不知道
AddChild
在第一个过程中依赖于
T
AddChild
可以通过使用
this->
在调用前加上前缀,从而在
T
已知时将查找延迟到第二个过程,从而使其成为从属名称。

我有两个具有相同构造函数的对象,它们都继承自ElementEx。我想说新对象,告诉它是哪种类型,然后得到正确的对象。我不想在构造函数之间维护重复的代码:(也许我看问题的方式不对。我会再考虑一下。此外,我似乎没有is_base_of。看起来我没有使用C++11之类的东西。我有两个具有相同构造函数的对象,都是从ElementEx继承的。我想说新对象,告诉它哪种类型,然后得到正确的类型。我不想维护重复的代码跨越构造器:(也许我看问题的方式不对。我会再考虑一下。此外,我似乎没有什么基础。看起来我没有使用C++11的东西。这是一个打字错误。修复了。好的,谢谢关于ElementEx::AddChild的附加信息。对于代码中的错误,我很抱歉;我很快地简化了它,错过了一些stu。)ff.:(编辑代码以显示您的修复。这是一个打字错误。已修复。好的,感谢您提供有关ElementEx::AddChild的附加信息。对于代码中的错误,我深表歉意;我很快将我的代码简化,并遗漏了一些内容。:(编辑代码以显示您的修复。这是一个问题吗?如果
a
B
是“什么东西”它实现了
AddChild
,这将很好地编译。如果它们是不同的东西,它将崩溃(这正是人们想要的!)。因此,无论哪种方式,它都可以像现在这样,不是吗?你可以简单地创建“东西”类型为
T
,没有该类型转换。要么
T
是正确的类型,要么编译器会吐出错误。我是getti
class ElementEx
{
public:
    ElementEx() {}
    void AddChild(ElementEx* element)
    {
        // some stuff
    }
};

class A : public ElementEx
{
public:
    A() {}
};

class B : public ElementEx
{
public:
    B() {}
};


template <class T>
class MyNewClass : public T
{
public:
    MyNewClass()
    {
        ElementEx* newElement = new ElementEx();
        this->AddChild(newElement);
    }
};

struct Bad {};

int main()
{
    MyNewClass<B> b;          // Compiles.
    MyNewClass<Bad> bad;      // error: 'class MyNewClass<Bad>' has no member named 'AddChild'
}