相关疑难解决方法(0)

std :: initializer_list返回值的生命周期

GCC的实现破坏了std::initializer_list返回full-expression结束时从函数返回的数组.它是否正确?

此程序中的两个测试用例都显示在使用值之前执行的析构函数:

#include <initializer_list>
#include <iostream>

struct noisydt {
    ~noisydt() { std::cout << "destroyed\n"; }
};

void receive( std::initializer_list< noisydt > il ) {
    std::cout << "received\n";
}

std::initializer_list< noisydt > send() {
    return { {}, {}, {} };
}

int main() {
    receive( send() );
    std::initializer_list< noisydt > && il = send();
    receive( il );
}
Run Code Online (Sandbox Code Playgroud)

我认为该计划应该有效.但潜在的标准有点令人费解.

return语句初始化一个返回值对象,就像它被声明一样

std::initializer_list< noisydt > ret = { {},{},{} };
Run Code Online (Sandbox Code Playgroud)

initializer_list将从给定的初始化器系列初始化一个临时及其底层数组存储,然后initializer_list从第一个初始化器初始化另一个.阵列的寿命是多少?"数组的生命周期与initializer_list对象的生命周期相同." 但其中有两个; 哪一个是模棱两可的.8.5.4/6中的示例(如果它按照公布的方式工作)应该解决数组具有复制到对象的生命周期的歧义.然后返回值的数组也应该存在于调用函数中,并且应该可以通过将它绑定到命名引用来保留它.

LWS上 …

c++ lifetime initializer-list c++11 list-initialization

25
推荐指数
2
解决办法
4610
查看次数

GCC 对可能有效的代码抛出 init-list-lifetime 警告?

我在带有 GCC 9.3.0 的 Debian 不稳定版上运行。

最近我参与的一个项目发生了变化,引入了类似于下面的代码。

#include <initializer_list>
#include <map>
#include <vector>

std::map<int, std::vector<int>> ex = []{
    /* for reused lists */
    std::initializer_list<int> module_options;

    return (decltype(ex)) {
        {1, module_options = {
            1, 2, 3
        }},
        {2, module_options},
    };
}();
Run Code Online (Sandbox Code Playgroud)

这个想法是初始化列表的相同子部分首先在顶部声明,std:initializer_list在第一次使用时定义并分配给变量,然后在多个地方使用。这很方便,有些人可能会争辩说更具可读性,这就是它被接受的原因。

一切都很好,直到几天前 GCC 开始init-list-lifetime对代码发出警告。我们-Werror在回归中使用,所以这对我来说回归失败了。我还尝试使用 clang 9.0.1 进行编译,但不会引发警告。

<source>: In lambda function:
<source>:12:9: warning: assignment from temporary 'initializer_list' does not extend the lifetime of the underlying array [-Winit-list-lifetime]
   12 |         }},
      |         ^
Run Code Online (Sandbox Code Playgroud)

根据cppreference …

c++ gcc language-lawyer c++11

6
推荐指数
1
解决办法
372
查看次数