gpt4 book ai didi

c++ - 为什么聚合结构可以用大括号初始化,但不能使用与大括号初始化相同的参数列表来放置?

转载 作者:可可西里 更新时间:2023-11-01 17:38:53 25 4
gpt4 key购买 nike

好像this code :

#include <string>
#include <vector>

struct bla
{
std::string a;
int b;
};

int main()
{
std::vector<bla> v;
v.emplace_back("string", 42);
}

在这种情况下可以正常工作,但它不能(我明白为什么)。为 bla 提供构造函数可以解决这个问题,但会消除类型的聚合性,这可能会产生深远的影响。

这是对标准的疏忽吗?还是我错过了某些情况,在这些情况下它会在我面前爆炸,或者它没有我想象的那么有用?

最佳答案

Is this an oversight in the Standard?

它被认为是标准中的缺陷,跟踪为 LWG #2089 ,由 C++20 解决。在那里,构造函数语法可以对聚合类型执行聚合初始化,只要提供的表达式不会调用复制/移动/默认构造函数。由于所有形式的间接初始化(push_backin_placemake_* 等)显式使用构造函数语法,它们现在可以初始化聚合。

在 C++20 之前,一个好的解决方案是难以捉摸的。

根本问题在于您不能随意使用花括号初始化列表。使用构造函数的类型的列表初始化实际上可以隐藏构造函数,这样某些构造函数就无法通过列表初始化来调用。这是 vector<int> v{1, 2};问题。这将创建一个 2 元素 vector ,而不是唯一元素为 2 的 1 元素 vector 。

因此,您不能在 allocator::construct 这样的通用上下文中使用列表初始化.

这将我们带到:

I would think there's be a SFINAE trick to do that if possible, else resort to brace init that also works for aggregates.

这需要使用 is_aggregate来自 C++17 的类型特征。但这有一个问题:然后您必须将这个 SFINAE 技巧传播到所有 使用间接初始化的地方。这包括 any/variant/optionalin_place构造器和炮台,make_shared/unique电话等等,没有一个使用allocator::construct .

并且这不包括需要这种间接初始化的用户代码。如果用户不进行与 C++ 标准库相同的初始化,人们会很不高兴。

这是一个棘手的问题,需要以不将间接初始化 API 分成允许聚合的组和不允许聚合的组的方式来解决。有many possible solutions , 它们都不是理想的。

语言解决方案是同类产品中最好的。

关于c++ - 为什么聚合结构可以用大括号初始化,但不能使用与大括号初始化相同的参数列表来放置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43407814/

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