我有以下格式的树结构:
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> { ... }
但我只是不断收到编译错误。任何帮助将不胜感激!
答案 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;
};