同样的叮当声,std::initializer_list 程序与 -std=c++14/-std=c++17 的结果不同

NoSenseEtAl

首先,这是一个好奇的问题,我永远不会在现实生活中编写这样的代码。

以下代码与 -O3 -std=c++14 和 -O3 -std=c++17 标志的行为不同,在 C++14 中我得到了错误的分配,我推测是从垃圾 std::string 的复制构造:

#include<algorithm>
#include<numeric>
#include<vector>
#include<string>
#include<iostream>

using namespace std;
static auto results = std::initializer_list<string>{"1                               ",
"2"};
string f() {

    auto result = std::accumulate(results.begin(), results.end(), string(""));
    return result;

}

int main()
{
    return f().size();
}

https://godbolt.org/z/H-Xzei

我的猜测是 C++17 版本比 C++14 版本保持底层数组的存活时间更长,但我发现 cppreference 上的初始化列表从 C++14 到 C++17 没有相关更改,所以我很困惑。这只是 UB 是 UB,还是语言发生了变化?

PS我知道如何解决这个问题,使用static const auto& results作品,就像之前提到的,这只是一个关于语言极端情况的问题。

巴里

这与保证复制省略有关,这是 C++17 中的新语言特性。

这一行(减少):

static auto results = std::initializer_list<string>{x, y};

在 C++14 中构造一个初始化列表,然后将它移动到results- 立即悬挂,因为initializer_list它不管理任何生命周期(astd::initializer_list有一个与初始对象具有相同生命周期的支持 const 数组 - 一旦初始initializer_list在结束时被销毁行,支持数组也是如此)。

换句话说,在 C++14 中,这个程序有未定义的行为。

在 C++17 中,它的行为完全类似于:

static std::initalizer_list<string> results{x, y};

在这种情况下,后备数组的生命周期与 相同results,即程序的长度。该程序具有明确定义的行为。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

C ++-std :: initializer_list与std :: span

C ++ std :: initializer_list用法

为什么C ++ 11中的std :: initializer_list重载了std :: begin()和std :: end()?

为什么std :: atomic构造函数在C ++ 14和C ++ 17中表现不同

c ++ 14 std :: experimental :: filesystem :: v1和c ++ 17 std :: filesystem之间的区别?

std :: initializer_list的实现

std :: initializer_list的实现

std :: initializer_list和c array []的优缺点是什么?

为什么C ++使std :: initializer_list的元素类型为const?

C ++ 11:编译器何时将{}视为std :: initializer_list,何时不考虑?

C ++将std :: initializer_list强制转换为模板化函数中的容器

为c样式的字符串创建std :: initializer_list构造函数

C ++ 11可以构造一个std :: initializer_list吗?

如何从嵌套的std :: initializer_list初始化2D C样式数组?

C ++构造函数采用大小为一的std :: initializer_list

如何将C数组转换为std :: initializer_list?

gcc 选项 std=gnu++17 与 std=c++17

std :: initializer_list可以专用吗?

std :: initializer_list和引用类型

std :: initializer_list构造函数

在clang中返回std :: initializer_list

自动功能中带有std :: initializer_list <int>且不带const的==测试的C ++ 1z处理

如何使CMake通过基于GCC版本的std = c ++ 14 / c ++ 1y或c ++ 17 / c ++ 1z?

C ++ 17 std ::在G ++中是可选的吗?

新的std :: map :: erase()签名C ++ 17

C++17 的 std::inserter 替换

在C ++ 17中更改std :: map :: insert

字符转换功能std :: isupper()和std :: islower()C ++ 17

C ++ 17无法使用std :: bind生成std :: function