使用初始值设定项列表进行emplace_back

emplace_back with initializer list

提问人:Yousef Irshaid 提问时间:7/1/2023 最后编辑:YSCYousef Irshaid 更新时间:7/1/2023 访问量:122

问:

我正在尝试在 VS2022 上运行以下代码:

#include <vector>
#include <initializer_list>

int main()
{
    std::vector<std::vector<int>> vec;
    //auto list = (std::initializer_list<int>){ 5, 6 };
    vec.emplace_back((std::initializer_list<int>) { 5, 6 });
    return 0;
}

但它给了我一个错误:

错误 C4576 括号内跟初始值设定项列表的类型是非标准的显式类型转换语法

期待一个表达式。

根据其他答案,这应该有效,但在 VS2022 上对我来说并非如此,甚至评论行也不起作用。我尝试使用 g++ 编译它并成功了。有什么想法为什么吗?

C++ 初始值设定项列表 emplace

评论

4赞 Pepijn Kramer 7/1/2023
您正在对整数数组进行“C”样式的强制转换。 应该工作。尽管在这个非常小的例子中,它对我来说看起来很奇怪(不要误会我的意思,MRE 是好的)vec.emplace_back(std::initializer_list{5, 6});

答:

4赞 HolyBlackCat 7/1/2023 #1

C 样式转换具有 形式 ,而不是表达式(它没有类型,依此类推)。(type)expression{...}

可能不允许这种语法的原因是 C 有一种叫做 复合文字 与语法 ,与强制转换相比,其行为截然不同,因此在 C++ 中将相同的语法重用为不同的事情可能是一个坏主意。(type){...}

你想要一个功能性的演员表,形式是.所以。type{...}std::initializer_list<int>{5, 6}

但如果我是你,我会用.是的,这使用了一个额外的动作,但语法更干净。.push_back({5, 6})

评论

0赞 Yousef Irshaid 7/1/2023
这是否构造了一个initializer_list然后将其复制到 vec 中?如果是这样,这违背了使用 emplace_back 的目的。
0赞 HolyBlackCat 7/1/2023
@YousefIrshaid 什么意思?列表的各个元素被复制到向量中(由于 的设计不佳,没有移动,但对于复制和移动是一回事),但当你这样做时,也会发生同样的事情。initializer_listintstd::vector<int> v = {1,2,3};
0赞 Yousef Irshaid 7/1/2023
我知道,在放回用户定义的类型时,我需要将构造函数参数传递给方法,以便将对象直接构造到向量中,而无需移动或复制。我想用 vector 实现相同的功能,你有什么建议?
0赞 HolyBlackCat 7/1/2023
@YousefIrshaid是最佳的。 由于多走一步,不太理想。.emplace_back(std::initializer_list<int>{1,2,3}).push_back({1,2,3})