gpt4 book ai didi

c++ - 引用/initializer_list 的生命周期

转载 作者:行者123 更新时间:2023-11-30 01:45:27 31 4
gpt4 key购买 nike

考虑以下示例:

第一个编译单元:

#include <vector>
#include <string>
#include <initializer_list>
#include <iostream>

struct DoubleString
{
std::string one;
std::string two;
};

class E
{
public:
E(std::initializer_list<DoubleString> init) : stringVec(std::move(init))
{}

void operator()()
{
for (auto const & x : stringVec)
{
std::cout << x.one << " " << x.two << std::endl;
}
}

private:
std::initializer_list<DoubleString> stringVec;
};

class F
{
public:
F( const std::string & one, const std::string & two) : e{ {one, two} }
{ }

void operator()()
{
e();
}

private:
E e;
};

class Caller
{
public:
void operator[](F f);
};


int main()
{
Caller()[ F{"This is string 1", "This is string 2"} ];
}

独立编译单元:

void Caller::operator[](F f)
{
f();
}

另见 http://coliru.stacked-crooked.com/a/b01d349fa8f22f62

用 gcc 和 clang 编译和运行这个,两个片段在一个编译单元中,输出是"这是字符串 1 这是字符串 2"

当我将 void Caller::operator [](F f) 移动到一个单独的编译单元时,它仍然适用于 gcc,但会因 clang 而中断(它会打印垃圾)。 Clang 地址清理器检测到:

==16368==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7ffc6602f388 at pc 0x0000006d036a bp 0x7ffc6602f340 sp 0x7ffc6602f338

当我使用 std::vector 作为变量 E::stringVec 的类型时,它再次适用于 clang。

看来我误用了 std::initializer_list。是否允许将其用作变量?为什么它适用于 gcc 但不适用于 clang?

顺便说一句:我喜欢 Coliru 作为在线编译器。有谁知道,如何定义单独的编译单元?

最佳答案

原文std::initializer_list<DoubleString>作为 F 的构造函数调用的一部分创建(将其传递给成员 e 时)。创建此 std::initializer_list<DoubleString>DoubleString对象被创建。 std::initializer_list<DoubleString>的生活因此,DoubleString e 时对象结束成员完成初始化。

然而,std::initializer_list<T>不是真正的值类型。它是可复制的,但拷贝不会创建拷贝,而只是将堆栈指针复制到用于创建 std::initializer_list<T> 的对象。 .这个,复制在E实际上指向一系列对象(好吧,只有一个),一旦原始 st::initializer_list<DoubleString> 被销毁消失了。也就是说,您只有未定义的行为。为什么事情在一种情况下有效而不是另一种情况并不十分清楚,但这在某种程度上是未定义行为的本质。

基本要点是:std::initializer_list<T>不是真正的一等公民。从本质上讲,这是一种获取堆栈分配对象序列而不复制它们以允许序列初始化的技巧。它确实在参数列表之外没有任何位置,参数列表应该能够使用无限数量的相同类型的参数。

关于c++ - 引用/initializer_list 的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34649928/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com