标准库类型的析构函数定义良好吗?



例如iterator类型-这里我需要根据使用情况拥有不同类型的多态迭代器。所以我用用户定义的构造函数和析构函数创建了一个联合:

我特别质疑析构函数的名称(例如。~iterator())。

#include <list>
#include <string>
struct val_origin {
union {
std::list<std::list<std::string>>::iterator iterenum;
std::list<std::list<std::list<struct var>>>::iterator iterunorstr;
std::list<struct var>::reverse_iterator vartypedef;
};
enum ORIG_ENUM {
ORIG_ENUM_TYPE,
ORIG_STRUC_TYPE,
ORIG_TYPEDEF,
ORIG_PLAIN
} orig;
val_origin(ORIG_ENUM orig) {
switch (orig) if (0)
case ORIG_ENUM_TYPE:
new (&iterenum)decltype(iterenum) {};
else if (0)
case ORIG_STRUC_TYPE:
new (&iterunorstr)decltype(iterunorstr) {};
else if (0)
case ORIG_TYPEDEF:
new (&vartypedef)decltype(vartypedef) {};
}
val_origin& operator=(const val_origin& val_origin_in) {
this->~val_origin();
new (this)val_origin{ val_origin_in };
}
val_origin(const val_origin& val_origin) {
switch (orig) if (0)
case ORIG_ENUM_TYPE:
iterenum = val_origin.iterenum;
else if (0)
case ORIG_STRUC_TYPE:
iterunorstr = val_origin.iterunorstr;
else if (0)
case ORIG_TYPEDEF:
vartypedef = val_origin.vartypedef;
}
~val_origin() {
switch (orig) if (0)
case ORIG_ENUM_TYPE:
iterenum.decltype(iterenum)::~iterator();
else if (0)
case ORIG_STRUC_TYPE:
iterunorstr.decltype(iterunorstr)::~iterator();
else if (0)
case ORIG_TYPEDEF:
vartypedef.decltype(vartypedef)::~reverse_iterator();
}
};

现在我的问题是上面的代码在gcc上编译得很好。但是当我切换到clang或MSVC时,它失败了。

我的问题是,如果这是一个标准代码或不是(将感谢引用标准,我无法找到相关信息),如果不是,我是什么其他的选择来实现这一点。

我试图有一个动态(运行时)多态迭代器(相同的对象,但不同类型的迭代器,将由代码的不同部分适当使用)。

代码在MSVC上失败,因为析构函数名称未知。

析构函数的名称查找非常微妙,以支持typedef-names对于非类类型。但是,不能保证iterator在这里可用,因为迭代器不必是命名为iterator(或reverse_iterator)的类型,以便将其作为注入的类名提供,并且由于没有对不合格的声明查找。

此外,经过最近的澄清,规则是decltype(…)::~…只是无效的([exp .prim.id.qual]/4)。当然,限定的理由很少。析构函数" names ":你可以直接写

iterenum.~decltype(iterenum)();

等等

您可能应该使用c++机制(具有不同替代方案的派生类),而不是非常低级的Cunion。您必须查看生成的代码以检查是否有运行时开销(如果有的话)。我怀疑这种不寻常的结构(类对象的union)可能会混淆一些编译器,从而为(虚拟或其他)方法/字段访问生成不正确的代码。

最新更新