库类型的析构函数是否定义明确?
Are destructors of library types well defined?
例如 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 上失败,因为析构函数名称未知。
您可能应该使用 C++ 机制(派生 classes 和不同的替代方案)而不是——非常低级的——C union
。您必须查看生成的代码以检查运行时开销(如果有)。我怀疑这种不寻常的构造(class 个对象的 union
)可能会使某些编译器混淆,从而为(虚拟或其他)method/field 访问生成不正确的代码。
析构函数的名称查找非常微妙,可以支持诸如 typedef-names 之类的非 class 类型。但是,不能保证 iterator
在这里可用,因为迭代器不需要是名为 iterator
(或 reverse_iterator
) 以便将其作为注入-class-名称提供,因为没有声明 unqualified 查找。
此外,在最近的澄清之后,规则是 decltype(…)::~…
只是无效的 ([expr.prim.id.qual]/4)。当然,没有什么理由 限定 析构函数的“名称”:你可以只写
iterenum.~decltype(iterenum)();
等等。
例如 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 上失败,因为析构函数名称未知。
您可能应该使用 C++ 机制(派生 classes 和不同的替代方案)而不是——非常低级的——C union
。您必须查看生成的代码以检查运行时开销(如果有)。我怀疑这种不寻常的构造(class 个对象的 union
)可能会使某些编译器混淆,从而为(虚拟或其他)method/field 访问生成不正确的代码。
析构函数的名称查找非常微妙,可以支持诸如 typedef-names 之类的非 class 类型。但是,不能保证 iterator
在这里可用,因为迭代器不需要是名为 iterator
(或 reverse_iterator
) 以便将其作为注入-class-名称提供,因为没有声明 unqualified 查找。
此外,在最近的澄清之后,规则是 decltype(…)::~…
只是无效的 ([expr.prim.id.qual]/4)。当然,没有什么理由 限定 析构函数的“名称”:你可以只写
iterenum.~decltype(iterenum)();
等等。