带指针的C ++类模板专业化

时间:2016-01-28 19:27:24

标签: c++ class templates pointers

我有以下格式的树结构:

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; 
};

我在程序中使用了这个模板的各种实例。它运作得很好。

然而,一个实例化使用DataType只是一个枚举(所以它与指针的大小相同!)并且因为速度是必不可少的(无论是在构建树时,还是在访问时) ,我宁愿让这个实例化直接使用枚举而不是指针。我希望代码看起来(不严格)的一个例子:

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

现在我当然可以保留当前模板,但我不喜欢这种额外的指针访问,而尤其需要在root中分配int。关于如何专门化模板以提供此功能或其他方法的任何想法?

我试图像这样专门化模板(以及其他许多方式)

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

但我只是不断收到编译错误。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

我建议使用相同的接口定义多个data类,您可以将其用作DataType模板参数。摘要从数据访问方式中存储数据的方式。

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; }
};

然后,在您的Tree课程中,您可以通过他们的公共界面使用它们:

template <typename DataType>
class Tree {

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

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

答案 1 :(得分:1)

我建议使用traits类来推断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;
};

然后为TreeDataType专门设置MyEnum

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