- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下代码在以 Release模式编译的 Visual Studio 2019 上失败。
#include <iostream>
#include <iterator>
#include <initializer_list>
int main( int, char** )
{
std::initializer_list<int> v = {};
std::initializer_list<int> i = { 1, 2, 3 };
v = i;
std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, " " ) );
std::cout << std::endl;
v = { 1, 2, 3 };
std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, " " ) );
std::cout << std::endl;
}
v 的第二次初始化似乎失败了,输出如下:
1 2 3
17824704 10753212 0
但是在 Debug模式下构建或使用其他编译器(gcc、clang)构建时。输出如预期:
1 2 3
1 2 3
这可能是什么原因?
最佳答案
为了清楚起见,v
的唯一初始化发生在以下行:
std::initializer_list<int> v = {};
另外两个是赋值而不是初始化:
v = i;
v = { 1, 2, 3 };
正是这两个任务之间的差异提供了解决方案。
i
至
v
,
i
的底层数组(因此
v
)继续存在,直到在
main
结束时超出范围.那里没有问题。
{1, 2, 3}
至
v
,底层数组也将继续存在,直到超出范围。不幸的是,一旦赋值完成,这就会发生,这意味着使用
v
的元素在那之后会有问题。
v
很可能仍然有一个指针和长度,指针指向的东西已经超出范围,并且该内存很可能已被重用于其他东西。
C++20 [dcl.init.list] /6
)中的相关文本在谈论初始化列表时指出:
The [underlying] array has the same lifetime as any other temporary object, except that initializing an
initializer_list
object from the array extends the lifetime of the array exactly like binding a reference to a temporary.
C++20 [class.temporary] /4
覆盖。 :
Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created.
// initializer_list example
#include <iostream> // std::cout
#include <initializer_list> // std::initializer_list
int main ()
{
std::initializer_list<int> mylist;
mylist = { 10, 20, 30 };
std::cout << "mylist contains:";
for (int x: mylist) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
虽然这在某些情况下可能有效,但绝不能保证,事实上,
gcc 10.2
(检查
Compiler Explorer )正确地将其视为有问题的:
<source>: In function 'int main()':
<source>:8:25: warning: assignment from temporary 'initializer_list'
does not extend the lifetime of the underlying array
[-Winit-list-lifetime]
8 | mylist = { 10, 20, 30 };
| ^
关于c++ - 为什么在 VS2019 中 std::initializer_list 的初始化似乎失败了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63445675/
我需要使用 initializer_list 来初始化编译时大小的类数组。我已经知道我可以使用参数包构造函数并当场初始化它,但在这种情况下我需要使用 initializer_list。如果可能,我还想
我有一个类构造函数接受一个 initializer_list 这个构造函数必须运行接受一个的父类构造函数 initializer_list>. 所以我必须将初始化列表转换为二维初始化列表。 {1, 2
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: initializer_list and move semantics 环境:Linux,g++-4.7 我使
以下代码编译并运行: #include #include #include #include void ext( std::initializer_list >> myList ) {
std::vector的初始化列表构造函数具有以下形式 vector( std::initializer_list init, const Allocator& alloc = Allocator()
考虑以下代码片段... void boo(std::initializer_list l) { } template void foo(std::initializer_list l) {
我的问题是关于 std::initializer_list 之间缺乏转换当这些转换看起来很容易实现时,包含的类型或多或少是 cv 限定的类型。 考虑以下无效代码: std::initializer_l
我的图表构造函数: Graph(std::initializer_list list); 我的边缘构造函数: Edge(int out, int in); 我想通过以下方式创建我的图表: Graph
我有一些我想在编译时由需要某种程度验证的初始化列表初始化的类。 我首先尝试使用static_assert,但不会与错误“静态声明的非恒定条件”一起编译 造成此错误的最佳方法是什么? class foo
//parameter pack sum example constexpr int sum(int N= 0) { return N; } template constexpr int su
我是新来的,这是我的第一个问题。 所以,我有这个功能: std::string join(string_initializer_list p_input) const { std::strin
想问一下有没有机会补上引用功能。假设我有功能: double refce( double (&f1)(double), double in ){ return f1(in); } 而不是这样调
所以我昨天尝试开始使用 std::initializer_list 但这并不是一个巨大的成功。这是我最后的尝试之一: #include #include struct XmlState
考虑函数: template void printme(T&& t) { for (auto i : t) std::cout ({'a', 'b', 'c'})); printme(st
考虑函数: template void printme(T&& t) { for (auto i : t) std::cout ({'a', 'b', 'c'})); printme(st
我想用 std::initializer_list 初始化基类。 struct A : public std::array { // This constructor works fine A
基于这段代码 struct Foo { Foo() { cout ilist) { cout 构造函数的大括号初始化中。 相反,复制构造函数带头。 你
尝试为 Node 安装 phash-image 但出现此错误: > phash-image@3.1.0 install /Users/jong/Workspace/mgmtio/phash-image
下面对 foo 的调用是否有效? GCC 似乎对此很满意,而 Clang 为 foo 给出了“无匹配函数”错误;以及无法推断出 N 的注释。 template void foo(const int
我正在尝试使用函数模板 foo 将参数转换为 initializer_list。但是,它转换的 initializer_list 具有与输入参数不同的奇怪值。 #include #include
我是一名优秀的程序员,十分优秀!