【问题标题】:Can I tell which template instance class(es) my class is inheriting from?我可以告诉我的类继承自哪个模板实例类吗?
【发布时间】:2014-04-05 14:54:03
【问题描述】:

鉴于此代码:

template < int I >
class Foo
{
public:
    int v;
    Foo() { v = I; }
    virtual ~Foo() {}
};

class Bar : public Foo<0>, public Foo<3>
{
public:
    template < int I >
    int getValue() { return Foo<I>::v; }
};

int main() {
    Bar b;
    cout << b.getValue<0>() << endl; // prints 0
    cout << b.getValue<3>() << endl; // prints 3
    cout << b.getValue<4>() << endl; // compiler error
    return 0;
}

是否可以遍历所有 Foo&lt;i&gt; 继承自 Bar 的类?我们可以假设 i 介于 0 和某个最大值 N 之间。在伪代码中:

for ( int i = 0; i < N; i++ )
{
    if ( Bar inherits from `Foo<i>` )
    {
        cout << Foo<i>::v << endl;
    }
}

【问题讨论】:

  • 如果您在i 上有一个上限,那么您可以编写一个递归函数模板,为0 和您的上限之间的每个i 值调用boost::is_base_of&lt;YourClass, Foo&lt;i&gt; &gt;

标签: c++ templates inheritance reflection multiple-inheritance


【解决方案1】:

给你(live example):

struct _do { template <typename... A> _do(A&&...) { } };

template <int... I>
class Bar_impl : public Foo<I>...
{
public:
    template < int K >
    int getValue() { return Foo<K>::v; }

    template <typename F>
    void loop(F&& f) { _do{(std::forward<F>(f)(getValue<I>()), 0)...}; }
};

using Bar = Bar_impl<0,3>;

现在Bar 实现将基类的所有索引保存在可变参数I... 中,并以可变参数方式派生所有基类Foo&lt;I&gt;...

函数loop 使用辅助struct _do 遍历所有碱基。您可以将任意函数、lambda 或函数对象f 传递给loop。然后将在 getValue&lt;I&gt;() 上为所有 I... 调用 f,即在每个基类的成员 v 上。

您按如下方式使用它:

void print(int i) { cout << i << " "; }

int main() {
    Bar b;
    b.loop(print); // prints 0 3
    cout << endl;
}

换句话说,你不需要检测一个对象是否是某个类的实例。您通过构造使对象知道它自己的基础。

现在您可能会意识到,如果您将Foo 设为成员类型的模板(而不是int),您就可以开始构建自己的very basic tuple

【讨论】:

  • 干杯。不幸的是,我可能无法访问我的项目中的 C++11 功能。这样的事情在 pre-11 C++ 中仍然可行吗?
  • 是的,但不是那么方便。对于Bar 的定义和函数loop,您必须使用递归。 Here 是一个递归元组定义,我把它变成了非递归的。您可以对Bar 使用相同的模式。我猜loop 会容易得多。知道而不是检测的想法保持不变。
  • @suszterpatt 因为这里没有可变参数模板,所以您必须使用类似node&lt;0,node&lt;3,node&lt;5&gt; &gt; &gt; 的结构构建Bar&lt;0,3,5&gt;,同时继承Foo&lt;0&gt;node&lt;3,node&lt;5&gt; &gt; 等,如果你知道的话我的意思。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-13
相关资源
最近更新 更多