C++ class template specialization with pointers

与世无争的帅哥 提交于 2019-12-25 10:00:32

问题


I have a tree structure of the following format:

template <typename DataType>
class Tree {

    DataType *accessData() { return data; } 

    Tree *child1, *child2;
    DataType *data;
};

template <typename DataType>
class Root : public Tree<DataType> {
    // root provides storage of nodes; when it goes out of scope, the
    // entire tree becomes invalid
    MemoryPool<Tree> nodeStorage;
    MemoryPool<DataType> dataStorage; 
};

I use a variety of instantiations of this template in my program. It works quite well.

One instantiation, however, uses a DataType which is just an enum (so it's the same size as a pointer!) and because speed is essential (both when the tree is built, and when it is accessed), I'd much rather have this instantiation use the enum directly instead of a pointer. An example how I'd like the code to look (not strict):

Tree<BigClass> *foo = ...;
foo->accessData()->doBigClassThings();
Tree<int> *bar = ...;
int x = 4 + bar->accessInt();

Now of course I could just keep the current templates but I don't like this extra pointer access and especially the need to allocate ints in the root. Any ideas on how I can specialize the template to provide this functionality, or other approaches?

I've tried to specialize the template like this (and a bazillion other ways)

template <> Tree<int> { ... }

But I just keep getting compile errors. Any help would be greatly appreciated!


回答1:


I would recommend using a traits class to deduce the type of object stored in Tree.

// The default traits.
template <typename DataType> struct TreeDataType
{
   using Type = DataType*;
};

template <typename DataType>
class Tree {

   // Define the data type using the traits class.
   using Data = typename TreeDataType<DataType>::Type;

   Data accessData() { return data; } 

   Tree *child1, *child2;
   Data data;
};

and then specialize TreeDataType for MyEnum.

template <> struct TreeDataType<MyEnum>
{
   using Type = MyEnum;
};



回答2:


I suggest defining multiple data classes with the same interface that you can use as DataType template parameters. Abstract the way the data is stored from the way the data is accessed.

template<typename T>
class value_data
{
private:
    T _value;

public:
    T& access() { return _value; }
    const T& access() const { return _value; }
};

template<typename T>
class unique_ptr_data
{
private:
    std::unique_ptr<T> _value;

public:
    T& access() { assert(_value != nullptr); return *_value; }
    const T& access() const { assert(_value != nullptr); return *_value; }
};

enum class my_enum { /* ... */ };

class my_enum_data
{
private:
    my_enum _value;

public:
    my_enum& access() { return _value; }
    const my_enum& access() const { return _value; }
};

Then, in your Tree class, you can use them through their common interface:

template <typename DataType>
class Tree {

    auto& accessData() { return data.access(); } 

    Tree *child1, *child2;
    DataType data;
};


来源:https://stackoverflow.com/questions/35070288/c-class-template-specialization-with-pointers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!