前几天在贝尔法斯特召开了C ++编程语言标准化委员会的会议。 大约400条C ++ 20的评论从国家代表进入委员会,其中一半设法解决了。
在削减之下,您正在等待俄罗斯评论(是的,您对C ++ 20的评论),来自其他国家的评论以及当然是合适的新C ++ 23(执行器!)的讨论结果。
人们在
stdcpp.ru上 ,在
@ProCxx聊天中,在Yandex.Taxi上或在会议中亲自提到的所有C ++问题,我们以对C ++ 20的评论的形式撰写。 所以呢...
std ::原子<int> a {}; 和std ::原子<int> b;
看起来很奇怪,但是变量
a和
b并未初始化为0。要将原子变量初始化为零,必须用{0}编写std :: atomic <int>;
这种行为是完全不明显的,许多开发人员都将自己烧死了。 委员会接受了我们对标准的评论,并且在C ++ 20中,std :: atomic_flag和std :: atomic的默认构造函数将分别以
透明状态和T()初始化变量。
性病::洗涤
从C ++ 17开始,该标准具有可怕的功能std :: launder。 委员会成员认为标准库开发人员和普通用户会想出应对方法。
实际上,事实证明在某些情况下无法使用此功能。 原则上是绝对不需要的:
struct C { const int c; }; std::vector<C> v = {C{1}}; v.pop_back(); v.push_back(C{2}); assert(v.back().c == 2);
如果严格遵守标准的规定,则取决于标准库的实现,编译器的功能和月相,assert可能会通过或失败。
在讨论该问题时,事实证明,优化(该标准描述了这种奇怪的行为)仅在其中一个编译器中实现,并没有带来明显的性能提升。
因此,从C ++ 20开始,您可以安全地将带有链接和常量字段的结构存储在std ::可选,std :: Variant,std :: vector,std :: deque等中。现在,placement new自动应用部分std逻辑: :清洗。
*这在构造函数中
这是等待我们失败的评论之一:
struct C { C(C&& other) noexcept : initial_(other.initial_) , secondary_(other.initial_)
根据当前规则,在
O_O行中
,编译器有权假定&other == this,因此,在上面的一行中,我们重写了other.initial_的值,需要重新读取它。
换句话说,编译器有权假定尚未创建的类使用从中构造对象的参数作为别名,因此,它可以生成非最佳代码。
一些编译器(例如,GCC)认为用户不会编写这样的耻辱,并且认为不可能混叠。
委员会拒绝了我们的言论“让我们假设不能混叠”。 事实证明,有些代码库具有可怕的骇客之处,而&other ==这样,人们还没有准备好对他们说再见。
运算符<=>和嵌入式编程
为了使飞船操作员工作,您需要<compare>头文件。 但是,它不在任何平台上都可用的头文件列表中(在可以在任何Iron上使用
的标准库的所谓
独立实现中 )。
现在它在列表上了:)
其余的
根据我们的其他评论,判决为“不在C ++ 20中”:
*我们希望__func__在constexpr中使用。
*我们希望该概念不要使用不完整类型,因为否则您会遇到多个违反ODR的情况。 但是,这句话产生了意想不到的积极影响:如果您在require中使用不完整类型,则编译器现在会发出警告。
*我们想更正std :: string的赋值运算符,以免发生此类混乱:
basic_string::operator=(charT c): double d = 3.14; std::string s; s = d;
委员会建议编写另一篇论文,并在C ++ 20之后对此进行更正。
*我们想终止std :: string_view中的临时行分配:
std::string foo(); std::string_view sv; sv = foo();
结果与之前的评论相同:委员会建议编写另一篇论文,并在C ++ 20之后对此进行更正。
*我们要求编译以下代码:
#include <type_traits> template <typename... Xs> auto f (Xs...) -> std::invoke_result_t<Xs...>;
有人告诉我们,一切都很复杂,几乎没有机会修复C ++ 20。
来自其他国家的评论
重大变化:从满足range :: contiguous_range概念的类型中添加std :: span的构造函数。 因此,现在可以从std :: vector和std :: string隐式创建span。 我们还从两个满足range :: contiguous_iterator概念的迭代器中添加了构造函数std :: string_view。
有趣的编辑期望<compare>。 在过去三年中,运算符<=>发生了很大变化。 他不再参与相等性的比较,因此,不再需要<compare>内容的三分之一。 一些国家已经注意到这一点-他们降低了标准。
非类型模板参数发生了很大的变化。 在C ++ 20中,
几乎可以将
任何带有constexpr析构函数和公共成员作为模板参数的
类(请参阅P1907)传递,即使该类包含浮点类型或链接。
我们还将缺少的const添加到标准的不同部分,更改了C ++ 20新增的某些函数的参数名称和顺序。 对于概念和范围,标准文本的缩写以及其他一些小东西,也有许多编辑。
数字TS
ZaMaZaN4iK和C ++ Numerics Work In Progress文件使
我激动不已 。 现在有针对C ++ 23的拿破仑式计划,旨在为用户提供一组新型的数字(wide_integer,integer,有理数)以及用于处理溢出和方便别名的辅助低级方法。
有人告诉我准备下一次会议的演讲,并介绍整个委员会的想法。
执行者
执行程序是C ++ 23的优先事项之一。 它们对于反应式编程是必需的,对于异步编程(网络,磁盘,进程等)是必需的,它们是协程隐藏的基础,并且应为第三方库提供单个接口。
同时,执行者应针对其内部实现优化算法。 例如,对于代码:
template <std::input_range Range> void MySort(Range& data) { namespace stdr = std::ranges; std::sort(GetGlobalExecutor(), stdr::begin(data), stdr::end(data), 42); }
GetGlobalExecutor()函数可以返回:
*单线程执行程序-它应在其线程上执行通常的std :: sort;
*多线程执行程序-它应该执行并行排序;
* GPU执行程序-它必须将数据移至视频卡的内存,在此处进行排序,然后将数据返回;
* NUMA执行器-...
* ...
到目前为止,要实现此类功能,您需要执行可怕的定制点对象(CPO),并将每种算法都转化为它们。 委员会不喜欢...
但是至少他们
预先批准了P0443-基本接口。 对于执行人,所有随后的句子都需要以P0443的补丁形式编写。
代替总数
现在,只有一次委员会会议将我们与C ++ 20分开。 只剩一点点...
好吧,每个想与委员会代表进行实时聊天的人-看看mitaps和C ++会议
(*) :
*
明斯克的Corehard*
C ++西伯利亚2020*
C ++俄罗斯2020*
圣 彼得斯堡C ++用户组*
莫斯科C ++聚会2019(*)骇客:如果您是演讲者,则无需支付会议门票。