gpt4 book ai didi

c++ - 可以从模板类型中自动获取基类的类型吗?

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

我正在尝试使用模板元编程来确定基类。有没有一种方法可以自动获取基类而无需显式特化每个派生类?

class foo { public: char * Name() { return "foo"; }; };
class bar : public foo { public: char * Name() { return "bar"; }; };

template< typename T > struct ClassInfo { typedef T Base; };
template<> struct ClassInfo<bar> { typedef foo Base; };

int main()
{
ClassInfo<foo>::Base A;
ClassInfo<bar>::Base B;

std::cout << A.Name(); //foo
std::cout << B.Name(); //foo
}

目前任何自动方法都需要选择第一个声明的基地,并且对于私有(private)基地将失败。

最佳答案

使用 C++11 和 decltype 是可能的。为此,当成员从基类继承时,我们将利用指向成员的指针不是指向派生类的指针。

例如:

struct base{
void f(){}
};
struct derived : base{};

&derived::f 的类型将是 void (base::*)(),而不是 void (derived::*)()。这在 C++03 中已经成立,但如果不实际指定它,就不可能获得基类类型。使用decltype,很简单,只需要这个小函数:

// unimplemented to make sure it's only used
// in unevaluated contexts (sizeof, decltype, alignof)
template<class T, class U>
T base_of(U T::*);

用法:

#include <iostream>

// unimplemented to make sure it's only used
// in unevaluated contexts (sizeof, decltype, alignof)
template<class T, class R>
T base_of(R T::*);

struct base{
void f(){}
void name(){ std::cout << "base::name()\n"; }
};
struct derived : base{
void name(){ std::cout << "derived::name()\n"; }
};

struct not_deducible : base{
void f(){}
void name(){ std::cout << "not_deducible::name()\n"; }
};

int main(){
decltype(base_of(&derived::f)) a;
decltype(base_of(&base::f)) b;
decltype(base_of(&not_deducible::f)) c;
a.name();
b.name();
c.name();
}

输出:

base::name()
base::name()
not_deducible::name()

如最后一个示例所示,您需要使用的成员实际上是您感兴趣的基类的继承成员。

但是还有更多缺陷:该成员还必须明确标识一个基类成员:

struct base2{ void f(){} };

struct not_deducible2 : base, base2{};

int main(){
decltype(base_of(&not_deducible2::f)) x; // error: 'f' is ambiguous
}

虽然没有编译器支持,但这是您可以获得的最好结果。

关于c++ - 可以从模板类型中自动获取基类的类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8709340/

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