简体   繁体   English

类型和initializer_list不完整

[英]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 of T '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 example std::unique_ptr ([unique.ptr]/5) and std::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM