问题标签 [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++ - std::strong_ordering 和 std::weak_ordering 的实际意义
我一直在阅读有关 C++20 的一致比较(即operator<=>
)的一些内容,但无法理解std::strong_ordering
和之间的实际区别是什么std::weak_ordering
(_equality
这种方式的版本也是如此)。
除了对类型的可替代性进行非常详细的描述之外,它实际上是否会影响生成的代码?它是否为如何使用该类型添加了任何约束?
希望看到一个真实的例子来证明这一点。
c++ - 通过 __VA_OPT__ 递归宏
用 编写递归宏是否合法__VA_OPT__
?
GCC 和 Clang 似乎不会递归替换,但我不确定它是否是故意的(因为__VA_OPT__
支持是最近的)。
C++ 规范(§19.3.1/3:
__VA_OPT__
):否则,替换包括扩展内容的结果作为当前类函数宏 在重新扫描和进一步替换之前的替换列表
上面突出显示的部分是否意味着不可能递归?
例如,要添加可变参数宏参数列表:
GCC 和 Clang 都RECURSE
在它们的后预处理中生成。
注意:如果可能的话,可以相当容易地编写更复杂的可变参数宏,例如连接,因为您可以创建自定义__VA_NO_OPT__
from __VA_OPT__
,它允许您为 1 和 2+ 参数提供完全独立的代码。
c++ - 在并行算法中使用 range::view::iota
由于在c++17中没有基于索引的并行算法,我想知道是否可以结合使用来模拟它。那是:ranges::view::iota
std::for_each
iota_view
似乎为适当的类型([range.iota.iterator])提供随机访问:
iota_view<I, Bound>::iterator::iterator_category
定义如下:(1.1) — 如果
I
模型Advanceable
,那么iterator_category
是random_access_iterator_tag
。(1.2) — 否则,如果
I
模型Decrementable
,iterator_category
则为bidirectional_iterator_tag
。(1.3) — 否则,如果
I
模型Incrementable
,iterator_category
则为forward_iterator_tag
。(1.4) — 否则,
iterator_category
是input_iterator_tag
。
上面的代码正确吗?iota_view
使用这种方式是否有任何性能损失?
编辑:我用range-v3、cmcstl2和 Intel 的PSTL做了一些测试。
使用 range-v3,上面的示例无法使用 GCC 8 编译。编译器抱怨begin
并end
具有不同的类型:
使用 cmcstl2 代码可以干净地编译,但不能并行运行。在我看来,它回退到顺序版本,可能是因为不满足前向迭代器的要求(https://godbolt.org/z/yvr-M2)。
有一个有点相关的 PSTL 问题(https://github.com/intel/parallelstl/issues/22)。
c++ - 在现代 C++ 中是否可以将字符串文字作为参数传递给 C++ 模板?
是否可以在“现代 C++”(C++17 或更高版本)中将字符串文字作为参数传递给 C++ 模板?
我意识到你可以用构造函数参数来做到这一点;我只是认为将它作为模板参数会更方便,而不是深埋在 cpp 文件中。我很好奇这是否是现代 C++ 的一个新特性。请参阅下面的伪代码,了解我正在尝试做的事情:
伪代码示例:
c++ - 比率乘法期间的 chrono::duration_cast 问题
我正在编写一些必须处理 NTP 时间的代码。我决定用 来表示它们std::chrono::duration
,我希望这能让我的时间数学更容易做。
NTP 时间由一个无符号的 64 位整数表示,高 32 位为纪元以来的秒数,低 32 位为小数秒。纪元日期是 1900 年 1 月 1 日,但这是与我在这里处理的问题不同的问题,我已经知道如何处理它。对于我正在使用的示例,假设 1970 年 1 月 1 日为一个纪元,以使数学更简单。
持续时间表示很简单:std::chrono::duration<std::uint64_t, std::ratio<1, INTMAX_C(0x100000000)>>
. 当我试图在 NTP 时间和我的系统时钟之间进行转换时,问题就出现了。
在我的系统上,std::chrono::system_clock::duration
是std::chrono::duration<int64_t, std::nano>
. 当我尝试std::chrono::duration_cast
在这两个持续时间之间进行施法时,我在任一方向都被大量截断。在调试器中跟踪它,我发现它与duration_cast
实现有关,它在 libstdc++、libc++ 和 boost::chrono 中以同样的方式失败。简而言之,要从 system 转换为 ntp 表示,它会乘以 8388608/1953125 的比率,并在另一个方向上乘以相反的比率。它首先乘以分子,然后除以分母。数学是正确的,但初始乘法会溢出 64 位表示并被截断,尽管实际转换(除法后)仍然很容易用这些位表示。
我可以手动进行此转换,但我的问题如下:
- 这是实现中的错误,还是只是一个限制?
- 如果有限制,我是否应该意识到这将是一个问题?我没有看到任何可能导致能够猜测这不起作用的文档。
- 是否有一种通用的方法来实现这一点,而不是同一个问题?
- 是否应该报告,向谁报告?
- 最后,如果当 C++20 出现时,我使用具有手动策划
to_sys
和from_sys
功能的 NTP 时钟,我是否能够简单地使用std::chrono::clock_cast
而不必担心其他微妙的问题?
这是我用来测试的代码和一些示例输出:
样本输出:
c++ - 模块会成为 C++20 的一部分吗?它会减少库的编译时间吗?
嗨,我是具有 2.5 年经验的全职 c++ 程序员。我对 C++14 的新特性感觉很好。我每天都用它们。然而,每次我编译我的代码时,都会花费很多时间,甚至超过 15 分钟。我浏览了有关如何使用前向引用、预编译头文件等减少编译时间的指南。但是,即使对于我喜欢尝试一些逻辑/新功能或库的小型 c++ 项目,编译仍然需要很长时间。我很少读到关于没有进入 C++17 的模块。我只是想知道它会成为 C++20 的一部分吗?它会减少编译时间吗?如果是这样,会减少多少?
c++ - Shouldn't `std::shared_ptr` use `std::default_delete` by default?
std::default_delete
can be specialized to allow std::unique_ptr
s to painlessly manage types which have to be destroyed by calling some custom destroy-function instead of using delete p;
.
There are basically two ways to make sure an object is managed by a std::shared_ptr
in C++:
Create it managed by a shared-pointer, using
std::make_shared
orstd::allocate_shared
. This is the preferred way, as it coalesces both memory-blocks needed (payload and reference-counts) into one. Though iff there are onlystd::weak_ptr
s left, the need for the reference-counts will by necessity still pin down the memory for the payload too.Assign management to a shared-pointer afterwards, using a constructor or
.reset()
.
The second case, when not providing a custom deleter is interesting:
Specifically, it is defined to use its own deleter of unspecified type which uses delete [] p;
or delete p;
respectively, depending on the std::shared_ptr
being instantiated for an Array or not.
Quote from n4659 (~C++17):
4 Requires:
Y
shall be a complete type. The expressiondelete[] p
, whenT
is an array type, ordelete p
, whenT
is not an array type, shall have well-defined behavior, and shall not throw exceptions.
5 Effects: WhenT
is not an Array type, constructs ashared_ptr
object that owns the pointerp
. Otherwise, constructs ashared_ptr
that ownsp
and a deleter of an unspecified type that callsdelete[] p
. WhenT
is not an array type, enablesshared_from_this
withp
. If an exception is thrown,delete p
is called whenT
is not an array type,delete[] p
otherwise.
6 Postconditions:use_count() == 1 && get() == p
.
[…]3 Effects: Equivalent to
shared_ptr(p).swap(*this)
.
My questions are:
- Is there a, preferably good, reason that it is not specified to use
std::default_delete
instead? - Would any valid (and potentially useful?) code be broken by that change?
- Is there already a proposal to do so?
c++ - 现代 C++ 会支持 C#“Object Initalizer”语法吗?
我很好奇现代 c++ 标准人们是否考虑或添加了 C# 的“对象初始化器”语法。例如,在 C# 中,我可以在初始化期间像这样初始化对象的成员:
如果标准人们计划将“对象初始化器”语法添加到现代 C++ 中,那将非常方便,即。C++11、C++14、C++17、C++20等...
它目前是否存在于现代 C++ 规范中?
c++ - 使用概念启用类模板的成员函数
所以我有一个概念Fooable
:
而且我有一个Bar
将类型T
作为模板参数的类模板,并且我只想在以下情况下启用成员T
函数Fooable
:
是否可以在 C++17 中使用概念 TS 或在 C++2a 中?
c++ - 临时范围上的基于范围的 for 循环
由于 valgrind 中的一些分段错误和警告,我发现这段代码不正确,并且在 for-range 循环中有某种悬空引用。
看起来好像begin
和end
是从一个临时的并且丢失在循环中的。
当然,一种解决方法是
但是,我想知道为什么for(auto e : f()[5])
会出现错误,以及是否有更好的方法或某种设计方法,f
甚至是容器(std::vector
)来避免这种陷阱。
使用迭代器循环更清楚为什么会发生这个问题(begin
并且end
来自不同的临时对象)
但在 for-range 循环中,如第一个示例所示,似乎很容易犯此错误。