问题标签 [c++20]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 检测编译时文字和常量
假设我想编写一个通用类来维护一个始终保持在两个值之间的整数。像这样的东西:
类不变量是Lower <= m_int <= Upper
. 当然 MyInt 应该具有整数通常具有的所有常用操作,例如赋值和算术运算符。如果一个操作要让它处于破坏其不变量的状态,MyInt 会抛出。然而,在许多情况下,这应该是编译时可检测到的。考虑这个示例代码:
对于std::integral_constant
,编写适当的构造函数是直截了当的。但是是否有可能编译时检测a
在范围内和c
不在d
范围内?分配的值要么是编译时已知的文字,要么是 constexpr 常量。
我已经尝试过 SFINAE-ing 等等,但我找不到从值语义到模板参数的方法,即使在这些情况下(我声称)这些值显然是编译时常量。
对于 C++17,该语言不提供实现此功能所需的工具是否属实?如果是,这是否会随着即将到来的 C++20 而改变?如果我正在寻找的东西是不可能的,这是什么原因?我的兴趣完全是教育性的,所以如果我遗漏了一些东西(比如文字实际上不是编译时常量或其他东西),我会很感兴趣。
注意:我知道f
通过引入自定义文字后缀并要求用户键入以下内容可以使大小写不那么难看:
我也知道提供这样的界面的可能性:
然而,这两种变通方法都带有一定的输入开销,并且不一定是惯用的 C++。
c++ - 固定大小的 std::span 与 std::array
C++20 包括std::span
,它“描述了一个对象,该对象可以引用一个连续的对象序列,该序列的第一个元素位于零位置”。它的界面非常接近std::array
,虽然它支持动态范围以及固定范围。
明显的区别是它std::array
拥有它的元素(因此它的析构函数会破坏它们)而std::span
不是。
还有什么array
不能用的span
吗?
c++ - 通用 lambda 的熟悉模板语法
对于 c++20,建议为通用 lambdas p0428r2.pdf添加以下语法
但是 gcc 8 中的当前实现不接受以下实例化:
这是 gcc 中的实现错误还是缺少语言功能?我知道我们谈论的是提案而不是批准的规范。
完整示例(与模板函数语法比较):
抱怨以下错误:
main.cpp:25:22: 错误:'>' 标记 f("Hello") 之前的预期主表达式;
c++ - 将非拥有位容器基于 std::vector 是个好主意吗? 标准::跨度?
在我的几个项目中,我越来越需要处理内存中的连续位序列 - 高效(*)。到目前为止,我已经编写了一堆可内联的独立函数,以选择“位容器”类型(例如uint32_t
)为模板,用于获取和设置位,将“或”和“与”应用于它们的值,定位容器,以位为单位的长度转换为以字节为单位的大小或容器中的长度等......看起来这是编写类的时间。
我知道 C++ 标准库有一个专门化的std::vector<bool>
,这被许多人认为是一个设计缺陷——因为它的迭代器不暴露实际bool
的 s,而是代理对象。无论这对于专业化来说是一个好主意还是一个坏主意,这绝对是我正在考虑的东西 - 一个显式的位代理类,希望它“总是”被优化掉(用constexpr
,noexcept
和很好地润滑inline
)。因此,我正在考虑可能std::vector
从标准库实现之一改编代码。
另一方面,我的预期课程:
- 永远不会拥有数据/位-它将接收起始位容器地址(假设对齐)和位长度,并且不会分配或释放。
- 它将无法动态或以其他方式调整数据大小 - 即使在保留与 std::vector::resize() 相同的空间量时也不行;它的长度将在其生命周期/范围内固定。
- 它不应该对堆一无所知(并且在没有堆时工作)
从这个意义上说,它更像是位的跨度类。那么也许从跨度开始呢?我不知道,跨度仍然不标准;并且跨度中没有代理...
那么什么是我实现的良好基础(编辑:不是基类)?std::vector<bool>
? std::span
? 两个都?没有任何?或者 - 也许我正在重新发明轮子,这已经是一个已解决的问题?
笔记:
- 位序列长度在运行时是已知的,而不是编译时;否则,正如@SomeProgrammerDude 建议的那样,我可以使用
std::bitset
. - 我的班级不需要“成为”跨度或“成为”向量,所以我没有考虑专门研究其中任何一个。
(*) - 到目前为止,SIMD 效率不高,但可能会在以后出现。此外,这可以在我们不 SIMDize 而是假装通道是正确线程的 CUDA 代码中使用。
c++ - 具有动态内存分配的 C++ constexpr 函数
作为一个说明性示例,给定一个 constexpr 字符串文字,我想将其转换为另一个 constexpr 数据结构。由于这种转换完全没有副作用,我希望有一种方法可以在编译时做到这一点(没有预处理器,但具有标准的 C++ 语言特性)。
现在,我确信有一次我读到了 C++2a(或更高版本)的一个潜在的未来特性,它允许在 constexpr 函数中进行动态内存分配,这肯定是我的问题的解决方案。- 但我找不到那个告诉我的文章了。
有没有办法在 C++ 中的 constexpr 上下文中执行动态内存分配,或者有人知道哪篇论文提出了这个建议吗?
c++ - 写概念的惯用方式,说类型是 std::vector
我有以下代码实现以下类型特征:
- 那种类型是
std::vector
- 该类型是
std::vector
整数
它有效,但非常冗长。
有没有更短/更好的方法来使用概念来编写这个?
我知道我可以从 range-v3 或其他类似库中窃取概念,但假设我想自己实现它。
c++ - 如果有std::barrier,为什么要std::latch?
从文档中可以很清楚地看出它们之间的区别在于std::barrier
可以多次使用并且std::latch
只能使用一次。
在我看来,这std::latch
只是一个特殊情况,std::barrier
它增加了限制而不是功能。最重要的是,文档说count_down
使用n
大于内部计数器的调用是未定义的行为,因此必须以编程方式强制执行此限制。
那么我们为什么需要std::latch
呢?
我唯一的猜测是,可以std::latch
在硬件级别以提高性能的方式实现不同的实现。
是什么原因?
c++ - 迭代器的 Range TS 和 C++20 概念是否需要使用 `operator->` 的能力?
我搜索了各种 Range TS 提案,包括 P0896,将范围合并到 C++20 中的提案。从我的阅读看来,该Iterator
概念在可解引用性方面提出的唯一要求是*t
产生某种类型的对象的有效语法。
由于是根据 be和 beInputIterator
定义的,两者都不需要支持,因此 Range TS 和 C++20 似乎不需要迭代器提供支持。Iterator
Readable
operator->
->
是这样吗?
c++ - 为合同指定违规处理程序
在 Rapperswil 的 C++20 工作草案中采用了对 C++ 中基于合约的编程的支持 。该语言功能的一部分是违反处理程序的概念,当违反合同时将调用该处理程序。
您可以安装自己的违规处理程序并发布发布版本,并选择在运行时启用强制执行。
但是本文添加的[dcl.attr.contract]中的措辞说:
程序的违规处理程序是“<code>noexcept opt function of (lvalue reference to
const std::contract_violation
) 返回void
”类型的函数,并以实现定义的方式指定。[...]不应该有设置或修改违规处理程序的编程方式。它是由实现定义的,如何为程序建立违规处理程序以及如何设置std::contract_violation
([support.contract.cviol]) 参数值,除非下面指定。
这对我来说很不清楚。一个实现如何允许我以非编程方式设置我自己的违规处理程序?我必须在 gcc、clang 和 msvc 上做什么?