6

有谁知道使用 CRTP 计算对象子类数量的方法?

假设我们有一个类似于以下的设置:

template <typename T>    
class Object
{
    ....  
};

const unsigned int ObjectSubClassCount = ...; 

class Subobject : public Object<SubObject>
{
    ....
};

class Second : public Object<Second>
{
    ....
};

等等,这样,使用 TMP,我们可能有一个常数 ( ObjectSubClassCount) 来表示子类的总数?

有谁知道这样做的方法?

编辑:我想稍后将结果用作模板参数,所以我需要使用 TMP 来完成...

4

2 回答 2

2

以后不需要将结果用作模板参数,我会尝试这样做:

// Class which increments a given counter at instanciation
struct Increment {
  Increment(std::size_t& counter)
  {
    counter++;
  }
};

// This is your template base
template <typename T>    
class Object
{
  private:
    // For every instanciation of the template (which is done for a subclass)
    // the class counter should get incremented
    static Increment incrementCounter;
};

// This is the global object counter
static std::size_t classCounter;

// Static Member Variable
template<typename T>
Object<T>::incrementCounter(classCounter);

没试过,但应该可以。要再次将结果用作模板参数(MPL),我在 MPL 方面没有足够的经验,但我怀疑这是可能的。

于 2012-06-20T06:59:14.787 回答
0

好的,所以我找到了一个……可以接受的答案。我认为如果子类完全不了解彼此(我的意思是,我们正在谈论一些函数式编程......),那将不会奏效。

这是一个解决方案。这绝对不是我想要的解决方案;然而,这是一个开始。我已经强制所有对象使用一种 CRTP 形式,但更多的是使用链表格式。这样,我们的子类必须派生自一个 Object<> 模板:

A:自身和 B:最近定义的子类

这是我的代码(我<type_traits>曾经使用过一个模板,只是一个注释)

template <typename T>   //SFINAE check for the existance of subclasscount static member
struct has_subclasscount
{

    template <typename U>
    static typename std::enable_if<sizeof(U::subclasscount) != 0, int>::type test(int);

    template <typename U>
    static char test(...);

    static const bool result = (sizeof(test<T>(0)) == sizeof(int))?(true):(false);
};


template <bool res, typename T>
struct return_subclasscount //the value to return is 0 if false
{
    static const int result = 0;
};


template <typename T>       
struct return_subclasscount<true, T>    //returns subclasscount only if the first parameter is true
{
    static const int result = T::subclasscount;
};


template <typename T>               //combines return_subclasscount and has_subclasscount
struct get_subclasscount
{
    static const int result = return_subclasscount<has_subclasscount<T>::result, T>::result;
};


template <typename This, typename Prev>
class Object
{
public:

    static const int subclasscount = 1 + get_subclasscount<Prev>::result;   //the subclass count
};


class sub1 : public Object<sub1, int>
{

};


class sub2 : public Object<sub2, sub1>
{

};


class sub3 : public Object<sub3, sub2>
{

};

最后 3 个空类是我们计算的子类。这是我们的头文件。在我们的主 .cpp 文件中,我们有:

int main() {

std::cout << sub3::subclasscount;

char c;
std::cin >> c;
}

运行它,我们得到一个简单的输出:

3

这证实了它已经奏效。现在,这个解决方案的一些缺点是:

  • 在添加之前,我们必须知道我们最后定义的子类是什么。
  • 我们必须跟上我们使用子类计数器的任何地方,始终将其修改为来自列表中的最后一个子类(这可以通过使用一致的“endoflist”子类来避免,这需要维护)

不过,好处包括我们不需要维护我们之前定义的任何子类。但是,我认为这个答案更多的是“起点”而不是“最终解决方案”;也许可以扩展的东西?

(此外,这很容易被滥用来形成一种树结构,其中subclasscount实际上表示树中任何给定节点的深度)

有人从这里有什么想法吗?

于 2012-06-20T08:16:54.143 回答