C++20 designated initializers

栏目: IT技术 · 发布时间: 5年前

内容简介:The C++20 standard provides new ways to initialize aggregates. These are:In this article, we will see how list initialization with designated initializers work.The designated initialization syntax allows to initialize non-static direct data members of a ty

The C++20 standard provides new ways to initialize aggregates. These are:

  • list initialization with designated initializers, that has the following forms:
    T object = { .designator = arg1 , .designator { arg2 } ... };
    T object { .designator = arg1 , .designator { arg2 } ... };
    
  • direct initialization, that has the following form:
    T object (arg1, arg2, ...);
    

In this article, we will see how list initialization with designated initializers work.

The designated initialization syntax allows to initialize non-static direct data members of a type T. Here is an example:

struct foo { int a; char c = 'a'; }
foo f { .a = 42 };

The class foo has two non-static data members, a and c . When initializing the object f , the member a is initialized with the syntax .a = 42 . In this context, .a is called a designator .

The following rules apply to designated initializers:

  • a designator must refer to a non-static direct data member
  • all the designator used in the initialization expression must follow the order of the declaration of the data members in the class
  • not all data members must have a designator, but those that do must follow the rule above
  • it is not possible to mix designated and non-designated initialization
  • desginators of the same data member cannot appear multiple times
  • designators cannot be nested

Let us see several examples to understand it better. Consider the following classes:

struct bar
{
   int x;
};
 
struct foo
{
   int    a;
   bar    b;
   char   c = 'a';
   double d;
};

The following inialization is allowed:

foo f1{};                         // OK: a =  0, b = {x = 0}, c = 'a', d = 0.0
foo f2{ .a = 42 };                // OK: a = 42, b = {x = 0}, c = 'a', d = 0.0
foo f3{ .a = 42, .c = 'b' };      // OK: a = 42, b = {x = 0}, c = 'b', d = 0.0
foo f4{ .a = 42, .b = {.x = 5} }; // OK: a = 42, b = {x = 5}, c = 'a', d = 0.0
foo f5{ .a = 42, .b = {5} };      // OK: a = 42, b = {x = 5}, c = 'a', d = 0.0

However, the following forms of initialization are illegal:

foo f6{ .d = 1, .a = 42 };       // ERROR: out-of-order
foo f7{ .a = 42, true, 'b', 1 }; // ERROR: mixed designated and non-designated
foo f8{ .a = 42, .a = 0 };       // ERROR: duplicate designator 
foo f9{ .b.x = 42 };             // ERROR: nested initializer
int arr[5] = { [0] = 42 };       // ERROR: array designators not allowed

Here are several more examples. Consider the following classes and functions:

struct A { int a, b; };
struct B { int b, a; };
struct C { int a, c; };
 
void f(A){}
void f(B){}
void f(C){}
void g(B){}

The following calls are permitted:

f({ .a = 1, .c = 2 }); // OK: calls f(C)
g({ .b = 1, .a = 2 }); // OK: calls g(B)

However, the following calls are, on the other hand, erroneous:

f({.a = 1, .b = 2});   // ERROR: ambiguous between f(A) and f(B)
f({.a = 1});           // ERROR: ambiguous call, f(A), f(B), or f(C)
g({.a = 1, .b = 2});   // ERROR: g(B) but designators are in the wrong order

A designated initializer, and only one, can be used to initialize a union. Let us consider the following union type:

union Foo
{
   int    a;
   bool   b;
   char   c;
   double d;
};

The following forms of initialization are correct:

Foo u1{};                    // OK: a = 0
Foo u2{ .a = 1 };            // OK: a = 1
Foo u3{ .c = 'b' };          // OK: c = 'b'

However, having more than one designator is not allowed:

Foo u4{ .a = 1, .b = true }; // ERROR: cannot have more than one element

Designated initialization is a feature that is also available in the C programming language. However, it is more relaxed than in C++. In C, it is possible to perform out-of-order designated initialization, to mix designated initializers and regular initializers, to nest designators, and to initialize arrays with designators. Therefore, in this aspect, C and C++ are not fully compatible.

Designated initializers are supported in VC++ 2019 169.1, GCC 8 and Clang 10.


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Windows高级调试

Windows高级调试

Mario Hewardt、Daniel Pravat / 聂雪军 / 机械工业出版社 / 2009-5 / 79.00元

本书主要讲解Windows高级调试思想和工具,并涉及一些高级调试主题。本书内容主要包括:工具简介、调试器简介、调试器揭密、符号文件与源文件的管理、栈内存破坏、堆内存破坏、安全、进程间通信、资源泄漏、同步、编写定制的调试扩展、64位调试、事后调试、Windows Vista基础以及应用程序验证器的测试设置等。本书内容详实、条理清楚。 本书适合Windows开发人员、Windows测试人员和Windo......一起来看看 《Windows高级调试》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具