在C++中创建自定义的类似树的数据结构器
Creating a custom comparable Tree-like data structor in C++
我有一个类型struct Type_Specifier
,我想表示一个可以比较的不可变树状结构。我有以下代码来说明我想要什么:
#include <vector>
struct Parameter_Specifier;
struct Type_Specifier
{
explicit Type_Specifier(void* tag = nullptr, std::vector<Parameter_Specifier> parameters = {})
: tag(tag), parameters(parameters) { }
Type_Specifier(const Type_Specifier&) = default;
Type_Specifier(Type_Specifier&&) = default;
Type_Specifier& operator=(const Type_Specifier&) = default;
Type_Specifier& operator=(Type_Specifier&&) = default;
~Type_Specifier() = default;
private:
// Points to an arbitray memory location (whose lifetime is not managed by this type)
void* tag;
std::vector<Parameter_Specifier> parameters;
public:
static bool operator ==(const Type_Specifier& left, const Type_Specifier& right)
{
if (left.tag != right.tag)
return false;
else if (left.parameters.size() != right.parameters.size())
return false;
else for (std::size_t i = 0; i < left.parameters.size(); i++)
{
if (!(left.parameters[i] == right.parameters[i]))
return false;
}
return true;
}
static bool operator <(const Type_Specifier& left, const Type_Specifier& right)
{
if (left.tag < right.tag)
return true;
else if (left.parameters.size() < right.parameters.size())
return true;
else if (left.parameters.size() > right.parameters.size())
return false;
else for (std::size_t i = 0; i < left.parameters.size(); i++)
{
if (left.parameters[i] < right.parameters[i])
return true;
else if (right.parameters[i] < left.parameters[i])
return false;
}
return false; // left == right
}
};
struct Parameter_Specifier
{
explicit Parameter_Specifier(Type_Specifier type = Type_Specifier(), std::vector<char> value = {})
: type(type), value(value) { }
Parameter_Specifier(const Parameter_Specifier&) = default;
Parameter_Specifier(Parameter_Specifier&&) = default;
Parameter_Specifier& operator=(const Parameter_Specifier&) = default;
Parameter_Specifier& operator=(Parameter_Specifier&&) = default;
~Parameter_Specifier() = default;
private:
Type_Specifier type;
// Arbitrary data (not a 'string' or sequence of 'characters')
std::vector<char> value;
public:
static bool operator ==(const Parameter_Specifier& left, const Parameter_Specifier& right)
{
if (!(left.type == right.type))
return false;
else if (left.value.size() != right.value.size())
return false;
else for (std::size_t i = 0; i < left.value.size(); i++)
{
if (left.value[i] != right.value[i])
return false;
}
return true; // left == right
}
static bool operator <(const Parameter_Specifier& left, const Parameter_Specifier& right)
{
if (left.type < right.type)
return true;
else if (left.value.size() < right.value.size())
return true;
else if (left.value.size() > right.value.size())
return false;
else for (std::size_t i = 0; i < left.value.size(); i++)
{
if (left.value[i] < right.value[i])
return true;
else if (left.value[i] > right.value[i])
return false;
}
return false; // left == right
}
};
但是,它当然不会编译,可能是由于struct Parameter_Specifier
不完整,并且运算符"<"和"=="未定义。
我的问题是这样的:如何修改上述类型使其编译和正常工作?(并且有效?
笔记:
- 此类型的目的是用于双向映射结构,以便能够在
struct Type_Specifier
和std::size_t
之间映射(即它需要同时是键类型和值类型) - 我将根据我对"=="和">"的定义定义其他比较运算符'!=',>,>="和"<=",为简洁起见,我在这里省略了它们
- 我很确定
a == b
等同于!(a < b) && !(b < a)
- 比较的顺序并不真正相关,因为它是一个严格的弱排序关系。
- 我希望
Type_Specifier
类型遵循 RAII 习语 Paramater_Specifier
类型仅用于Type_Specifier
子代,而不适用于其他任何地方- 我只喜欢使用C++标准库
我正在考虑将Type_Specifier::parameters
作为std::vector<Parameter_Specifier*>
但随后我将不得不手动管理分配,Type_Specifier
,这会导致明显的问题,因为那里Parameter_Specifier
不完整。
您在使用关系运算符时遇到问题。
1)对于operator==()
,你有两个选择:(a)一个带有一个参数的类/结构的方法(左参数,*this
,是隐式的),不能static
,或者(b)一个具有两个参数的外部函数(通常friend
)。您已将两种备选方案混合在一起,并使该方法static
。我强烈建议替代方案(b):外部功能。所以(算上有一个std::vector
的operator==()
)operator==()
Type_Specifier
可能是
friend bool operator== (const Type_Specifier & left,
const Type_Specifier & right)
{
return ( left.tag == right.tag )
&& ( left.parameters == right.parameters );
}
对于Parameter_Specifier
可能是
friend bool operator== (const Parameter_Specifier & left,
const Parameter_Specifier & right)
{
return ( left.type == right.type )
&& ( left.value == right.value );
}
2)operator<()
也是如此。此外,如果"left.tag < rigth.tag
"是false
,我认为你应该验证这不是true
left.tag > right.tag
。我对Type_Specifier
的建议(但行为不同;谨慎)是
friend bool operator< (const Type_Specifier & left,
const Type_Specifier & right)
{
return ( left.tag < right.tag )
|| ( ( left.tag == right.tag )
&& ( left.parameters < right.parameters ) );
}
对于Parameter_Specifier
,我的建议(行为不同;谨慎)是
friend bool operator< (const Parameter_Specifier & left,
const Parameter_Specifier & right)
{
return ( left.type < right.type )
|| ( (left.type == right.type )
&& (left.value < right.value ) );
}
3)拥有operator==()
和operator<()
他人的关系运算符很简单。对于Type_Specifier
friend bool operator!= (const Type_Specifier & left,
const Type_Specifier & right)
{ return ! (left == right); }
friend bool operator> (const Type_Specifier & left,
const Type_Specifier & right)
{ return (right < left); }
friend bool operator<= (const Type_Specifier & left,
const Type_Specifier & right)
{ return ! (right < left); }
friend bool operator>= (const Type_Specifier & left,
const Type_Specifier & right)
{ return ! (left < right); }
对于Parameter_Specifier
...井。。。用Parameter_Specifier
更改Type_Specifier
。
PS:对不起,我的英语不好。
- 链表,反向函数,数据结构
- 尝试创建排序的动态列表(数据结构)
- 如何读取文件中的数据并创建结构向量
- C++:使用 for 循环创建多个数据结构
- 如何在 C++ 中创建抽象类的对象或数据结构?
- 如何创建辅助数据结构来跟踪 c++ 中 decrease_key 操作的堆索引
- 是否值得两次通过文件进行迭代,以创建最小的数据结构
- 如何为我的 Vulkan 类创建此通用数据结构字段
- 在创建C 枚举和依赖数据结构时,如何避免重复自己
- 用于创建、可视化和算法操作数据结构的C++库
- 在C++中创建自定义的类似树的数据结构器
- 我可以读取输入数据并创建广义C++数据结构吗?
- 如何从 CGAL 中的坐标和拓扑列表创建Polyhedron_3数据结构
- 如何在c++中动态创建一个具有列表底层数据结构的队列
- 如何创建/设计数据结构
- 创建一个树数据结构-不同的方法
- 创建一个由链接平衡最佳表和双链表组成的数据结构
- 无法创建数组大小 [300][300] 的二维数据结构 - >堆栈溢出
- 线程分叉创建数据结构
- 如何在c++中创建树形数据结构