gpt4 book ai didi

c++ - 派生类模板中的条件覆盖

转载 作者:可可西里 更新时间:2023-11-01 16:37:57 24 4
gpt4 key购买 nike

我有一个 Container 类,它包含一些对象,这些对象的类型可以派生自某些基类(TypeATypeB 等)的任意组合.). Container 的基类具有返回指向所包含对象的指针的虚方法;如果包含的对象不是从预期的类派生的,这些应该返回 nullptr。我想根据 Container 的模板参数有选择地覆盖基础方法。我尝试如下使用 SFINAE,但它无法编译。我想避免为每种可能的组合专门化 Container,因为可能有很多组合。

#include <type_traits>
#include <iostream>

using namespace std;

class TypeA {};
class TypeB {};
class TypeAB: public TypeA, public TypeB {};

struct Container_base {
virtual TypeA* get_TypeA() {return nullptr;}
virtual TypeB* get_TypeB() {return nullptr;}
};

template <typename T>
struct Container: public Container_base
{
Container(): ptr(new T()) {}

//Override only if T is derived from TypeA
auto get_TypeA() -> enable_if<is_base_of<TypeA, T>::value, TypeA*>::type
{return ptr;}

//Override only if T is dervied from TypeB
auto get_TypeB() -> enable_if<is_base_of<TypeB, T>::value, TypeB*>::type
{return ptr;}

private:
T* ptr;
};

int main(int argc, char *argv[])
{
Container<TypeA> typea;
Container<TypeB> typeb;
Container<TypeAB> typeab;

cout << typea.get_TypeA() << endl; //valid pointer
cout << typea.get_TypeB() << endl; //nullptr

cout << typeb.get_TypeA() << endl; //nullptr
cout << typeb.get_TypeB() << endl; //valid pointer

cout << typeab.get_TypeA() << endl; //valid pointer
cout << typeab.get_TypeB() << endl; //valid pointer

return 0;
}

最佳答案

...或者您可以将方法更改为更简单的方法:

template <typename T>
struct Container: public Container_base
{
TypeA* get_TypeA() override
{
if constexpr(is_base_of_v<TypeA, T>)
return ptr;
else
return nullptr;
}

...
};

并依靠优化器消除任何皱纹。就像用一个函数(在最终二进制文件中)替换多个 return nullptr 函数一样。或者,如果您的编译器不支持 if constexpr,则移除死代码分支。

编辑:

... 或者(如果您坚持使用 SFINAE)沿着这些方向的东西:

template<class B, class T, enable_if_t< is_base_of_v<B, T>>...> B* cast_impl(T* p) { return p; }
template<class B, class T, enable_if_t<!is_base_of_v<B, T>>...> B* cast_impl(T* p) { return nullptr; }

template <typename T>
struct Container: public Container_base
{
...

TypeA* get_TypeA() override { return cast_impl<TypeA>(ptr); }
TypeB* get_TypeB() override { return cast_impl<TypeB>(ptr); }

private:
T* ptr;
};

关于c++ - 派生类模板中的条件覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52956804/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com