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

标签 c++ templates metaprogramming

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

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/

相关文章:

C++ 获取两个日期之间的日期

c++ - 在 C++ 的函数调用中完成强制转换是否真的有效?

c++ - C++将函数调用列表作为参数传递

c++ 模板类成员函数的部分特化

c++ - 有没有人尝试在 C++ 中实现类似 Haskell 的 case-of 语句?

c++11 可变参数编程,如何定义 vector 塔

ruby - method_missing 中的 attr_accessor

c++ - 如何在每 x 步*仅*显示值

c# - 在 c# 和 c 函数之间传递值和指针

c++ - std::is_assignable 和 const 指针对象