【发布时间】:2016-04-23 09:29:56
【问题描述】:
我有一个类型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 在那里不完整。
【问题讨论】:
-
“但是我必须手动管理分配” 不,您可以使用
std::vector<std::unique_ptr<Parameter_Specifier>>。 -
@πάνταῥεῖ 根本没有帮助,它只是创建了一个新错误
function "std::unique_ptr<_Ty, _Dx>::unique_ptr(const std::unique_ptr<_Ty, _Dx>::_Myt &) [with _Ty=Parameter_Specifier, _Dx=std::default_delete<Parameter_Specifier>]" cannot be referenced -- it is a deleted function没有修复任何错误,我也不知道如何编写一个表达式,给我一个(非空)std::vector<std::unique_ptr<Parameter_Specifier>>
标签: c++ c++11 tree operator-overloading incomplete-type