带有“递归”的所有孩子的静态变量

时间:2017-09-20 14:42:00

标签: c++ inheritance recursion static crtp

我有类似

的东西
struct Base{
  int x=0;
};

我希望所有的孩子都有一个静态变量“myint”,这样,在构建时,他们会为所有父母和他们自己累积myint的值。 (实际上在我的情况下,x是一个集合,我想要的是每个孩子的集合的联合)。

struct Derived : public Base {
  static int myint =1;
  Derived(){x+=myint;}
};

struct Derived2 : public Derived {
  static int myint = 2;
  Derived2(){x+=myint;}
};

因此Derived的x = 1,Derived2的x = 3.

我已经看到使用CRTP(static variable for each derived class)写一个BaseX类可以做到这样的事情:

template<class A>
struct BaseX : public Base {
  static int myint;
  BaseX() {Base::x+=myint;}
}

struct Derived : public BaseX<Derived>;

但是这种模式不能用于第二级继承。我尝试了多重继承,但当然,我得到的是x有两个值,每个值都有错误值(对于继承自Derived的部分,x = 1,对于从BaseX派生的部分,x = 2) )。

你是否看到任何解决这个问题的方法而不必在所有构造函数中调用(x + = myint)并在每个派生中定义myint?

3 个答案:

答案 0 :(得分:2)

not-int / enum类型的变体:

#include <iostream>
#include <set>
#include <string>

struct Base {
    std::set<std::string> x;
};

template <class BASE>
struct Derived : BASE {
    static const std::string my_str;
    Derived() {
        this->x.insert(my_str);
    }
};

struct Derived1 : Derived<Base> {};
template<>
const std::string Derived<Base>::my_str = "derived";

struct Derived2 : Derived<Derived1> {};
template<>
const std::string Derived<Derived1>::my_str = "derived2";

int main() {
    Derived1 d1;
    Derived2 d2;

    for (const auto & word : d1.x) {
        std::cout << word << std::endl;
    }

    for (const auto & word : d2.x) {
        std::cout << word << std::endl;
    }
}

答案 1 :(得分:0)

我会这样做:

#include <iostream>

struct Base {
    int x = 0;
};

template <class BASE, int MY>
struct Derived : BASE {
    static const int myint = MY;
    Derived() {
        this->x += myint;
    }
};

struct Derived1 : Derived<Base, 1> {};
struct Derived2 : Derived<Derived1, 2> {};

int main() {
    Derived1 d1;
    Derived2 d2;
    std::cout << d1.x << std::endl;
    std::cout << d2.x << std::endl;
}

答案 2 :(得分:0)

我要感谢Toxa Evtushenko的帮助。由于他的想法,我提出了这种变化,我相信这种变化可以通用的方式应用:

#include <iostream>
#include <set>
#include <string>

struct Base {
  std::set<std::string> x;
};

template<class DERIVED>
struct help{
  static const std::string my_str;
};

template <class BASE, class DERIVED>
struct Derived : BASE {
private:
  help<DERIVED> val;
public:
  Derived() {
    this->x.insert(val.my_str);
  }
};

struct Derived1a;
template<> const std::string help<Derived1a>::my_str = "Derived1A";

struct Derived1a : Derived<Base,Derived1a> {};

struct Derived1b;
template<> const std::string help<Derived1b>::my_str = "Derived1B";

struct Derived1b : Derived<Base,Derived1b> {};

struct Derived2;
template<> const std::string help<Derived2>::my_str = "Derived2";
struct Derived2 : Derived<Derived1a,Derived2> {};

int main() {
  Derived1a d1a;
  Derived1b d1b;
  Derived2  d2;

  for (const auto & word : d1a.x) {
    std::cout << word << std::endl;
  }

  std::cout << std::endl;

  for (const auto & word : d1b.x) {
    std::cout << word << std::endl;
  }

  std::cout << std::endl;

  for (const auto & word : d2.x) {
    std::cout << word << std::endl;
  }
}

当然欢迎更优雅的解决方案!