[英]Incomplete types and initializer_list
I am trying to model some meta data for serializing/de-serializing C++ objects. 我正在尝试为一些元数据建模,以对C ++对象进行序列化/反序列化。 Here is something that captures the nuts & bolts of what I need;
这是捕捉我所需要的基本要素的东西。 it compiles with GCC 5.2 (
g++ sample.cpp -std=c++14
) and with Clang 3.6 ( clang++ sample.cpp -std=c++14
). 它使用GCC 5.2(
g++ sample.cpp -std=c++14
)和Clang 3.6( clang++ sample.cpp -std=c++14
)进行clang++ sample.cpp -std=c++14
。
My question is about the struct TypeInfo
in the example. 我的问题是关于示例中的
struct TypeInfo
。 It contains an std::initializer_list
of itself. 它本身包含一个
std::initializer_list
。 Is this standards-conforming? 这符合标准吗?
#include <cstdint>
#include <initializer_list>
enum class TypeCode : std::uint8_t { BOOLEAN, INT, OBJECT, STRING, SENTINEL };
struct TypeInfo
{
TypeCode typeCode_;
char fieldName_[64];
union
{
std::uint16_t textMinLength_;
std::uint16_t objectVersionMajor_;
};
union
{
std::uint16_t textMaxLength_;
std::uint16_t objectVersionMinor_;
};
// set only if typeCode_ = OBJECT
std::initializer_list < TypeInfo > objectTypeInfos_;
};
int main()
{
TypeInfo const sti { TypeCode::STRING, "updatedBy", { .textMinLength_ = 0 }, { .textMaxLength_ = 16 } };
TypeInfo const iti { TypeCode::INT, "amount", { 0 }, { 0 } };
TypeInfo const oti { TypeCode::OBJECT, "startTime", { .objectVersionMajor_ = 1 }, { .objectVersionMinor_ = 0 }, {
TypeInfo { TypeCode::INT, "weekdays", { 0 }, { 0 } },
TypeInfo { TypeCode::INT, "timeOfDay", { 0 }, { 0 } },
TypeInfo { TypeCode::STRING, "timezone", { .textMinLength_ = 0 }, { .textMaxLength_ = 5 } }
} };
TypeInfo const noti { TypeCode::OBJECT, "schedule", { .objectVersionMajor_ = 1 }, { .objectVersionMinor_ = 0 }, {
TypeInfo { TypeCode::INT, "id", { 0 }, { 0 } },
TypeInfo { TypeCode::STRING, "description", { .textMinLength_ = 0 }, { .textMaxLength_ = 16 } },
TypeInfo { TypeCode::OBJECT, "startTime", { .objectVersionMajor_ = 1 }, { .objectVersionMinor_ = 0 }, {
TypeInfo { TypeCode::INT, "weekdays", { 0 }, { 0 } },
TypeInfo { TypeCode::INT, "timeOfDay", { 0 }, { 0 } },
TypeInfo { TypeCode::STRING, "timezone", { .textMinLength_ = 0 }, { .textMaxLength_ = 5 } }
} }
} };
}
That actually induces undefined behavior with current wording. 实际上,这会导致当前措词出现不确定的行为。 At the point of instantiation of
std::initializer_list<TypeInfo>
, TypeInfo
is incomplete, hence [res.on.functions]/(2.5) applies: 在
std::initializer_list<TypeInfo>
的实例化点, TypeInfo
不完整,因此适用[res.on.functions] /(2.5):
In particular, the effects are undefined in the following cases:
特别是在以下情况下,效果是不确定的:
(2.5) — if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.(2.5)—如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非该组件特别允许。
… and incomplete types are not specifically allowed for initializer_list
yet - however, that's clearly defective. …尚不明确允许
initializer_list
不完整的类型-但是,这显然是有缺陷的。 LWG issue 2493 opts to fix this: LWG 第2493期选择解决此问题:
The typical use-case of
std::initializer_list<T>
is for a pass-by-value parameter ofT
's constructor.std::initializer_list<T>
的典型用例用于T
的构造函数的按值传递参数。 However, this contravenes [res.on.functions]/2.5 because initializer_list doesn't specifically allow incomplete types (as do for examplestd::unique_ptr
([unique.ptr]/5) andstd::enable_shared_from_this
([util.smartptr.enab]/2)).但是,这违反了[res.on.functions] /2.5,因为initializer_list不允许特定类型的不完整类型(例如
std::unique_ptr
([unique.ptr] / 5)和std::enable_shared_from_this
([util.smartptr .enab] / 2))。A resolution would be to copy-paste the relevant text from such a paragraph.
一种解决方案是从该段中复制粘贴相关文本。
Ie your code is fine (and will be officially fine after resolution of the aforementioned DR). 也就是说,您的代码很好(并且在解决上述DR后会正式没事)。
§ [res.on.functions]/2: §[res.on.functions] / 2:
In particular, the effects are undefined in the following cases:
特别是在以下情况下,效果是不确定的:
[...][...]
(2.5) - if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.(2.5)-如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非该组件特别允许。
I see no such specific allowance for initializer_list
to be instantiated over an incomplete type (in either §[dcl.init.list] or §[support.init.list], at least as of N4296). 我没有看到针对
initializer_list
这种特殊的允许在不完整的类型上实例化(至少在N4296版本中,在§[dcl.init.list]或§[support.init.list]中)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.