C ++ std :: initializer_list的用法

关于initializer_list在C ++中的工作方式,我有几个问题。首先,说我们有(为简单起见,省略了std ::):

initializer_list<uint32_t> lst({ 5,4,3 }); // (*)

在Visual Studio中,我对该类进行了深入研究,只发现了以下两个构造函数:

constexpr initializer_list() noexcept : _First(nullptr),_Last(nullptr) {}

constexpr initializer_list(const _Elem* _First_arg,const _Elem* _Last_arg) noexcept
    : _First(_First_arg),_Last(_Last_arg) {}

所以我的第一个问题是:上面标有(*)的行,后面是否有某种语法糖允许使用此语法(或者可能是编译器的常规语法,以便他进行处理并正确设置所有内容) )?

从类的角度看,所有内容都是constexpr,所以我的结论是,它们都是在编译时完成的,但是我找不到关于该问题的任何具体解释。

下一个问题与先前的结论有点矛盾,但是由于我不确定发生的事情100%,所以我还是要问:如果我没有明确使用new initializer_list<int>({...});,{ {1}}是否曾经以任何方式使用动态内存(是否有某种用例)?

同样,这是一个愚蠢的问题,但是我想确切地了解该类发生了什么,以及它如何与内存发生冲突。

第三个问题是,假设我们有一个类似如下的代码:

initializer_list

在这种情况下,除了#include <iostream> using namespace std; class Test { public: Test(initializer_list<uint32_t>&& lst) { cout << "Size: " << lst.size() << endl; for (const uint32_t* i = lst.begin(); i != lst.end(); ++i) { cout << " " << *i; } cout << endl << endl; } }; int main(void) { Test t1({ 4,6,3 }); Test t2({ 6,3,2,8 }); return 0; } Test实例使用的方法以外,还有没有其他方法可以使用t1类的构造函数?当然,这从一开始就正确吗? t2确实会打印出正确的值,但是我要确保没有任何不正确的格式,例如'brace init list'cout被销毁(如果说这样的话甚至可能)在{ ... }使用它们之前?

这让我很烦,因为我对编写此类东西时C ++如何管理内存一无所知。

gsjdtt2009 回答:C ++ std :: initializer_list的用法

1

  

所以我的第一个问题是:上面标有(*)的行,后面是否有某种语法糖允许使用此语法(或者可能是编译器的常规语法,以便他进行处理并正确设置所有内容) )?

来自cppreference

  

注释

     

尽管缺少构造函数,但可以创建非空的初始化列表。在以下情况下隐式构造std :: initializer_list的实例:

     
      
  • 在列表初始化中使用了支撑初始化列表,包括函数调用列表初始化和赋值表达式(不要与构造函数初始化列表混淆)
  •   
  • braced-init-list绑定到auto上,包括在for循环范围内
  •   

2

  

下一个问题[...]:如果我未明确使用新的initializer_list({...});, initializer_list是否可以以任何方式使用动态内存(是否存在某种用例? )?

你为什么呢?它们的主要目的是将参数列表传递给构造函数。它们是围绕数组的轻量级包装器,该数组是由编译器动态构建的,允许您沿着

行编写代码
curl_setopt($curl,CURLOPT_HEADER,1);

3a

  

在这种情况下,除了用于t1和t2实例的方法之外,还有其他方法可以使用Test类的构造函数吗?

我不太了解您在这里的要求。我会这样写:

std::string s1{'a','b','c','d'};

3b

  

当然,这从一开始就正确吗?

您的代码没有错。

3c

  

例如,在cout使用“ brace init list” {...}之前(如果说这样的话甚至可能被销毁)?

再次从cppreference

  

基础数组是类型为const T [N]的临时数组,其中每个元素都从原始初始化程序列表的相应元素进行了复制初始化(除非缩小转换无效)。基础数组的生存期与任何其他临时对象相同,不同之处在于,从数组初始化initializer_list对象可以延长数组的生存期,就像将引用绑定到临时对象一样(但有相同的例外,例如用于初始化非临时对象)。 -static类成员)。底层数组可以分配在只读存储器中。

TL; DR:即使临时性也不会在两个随机的代码行之间不复存在。您可以放心使用功能参数Test t1{ 4,6,3 }; Test t2{ 6,3,2,8 }; 直到功能结束。

PS

只有在回答这个问题的一半时,我才意识到这不仅是3个问题,而且实际上还有更多问题。更好地关注问题中的一点。如果还有更多,请提出更多问题。

本文链接:https://www.f2er.com/3106533.html

大家都在问