问题标签 [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.

0 投票
2 回答
831 浏览

c++ - std::strong_ordering 和 std::weak_ordering 的实际意义

我一直在阅读有关 C++20 的一致比较(即operator<=>)的一些内容,但无法理解std::strong_ordering和之间的实际区别是什么std::weak_ordering_equality这种方式的版本也是如此)。
除了对类型的可替代性进行非常详细的描述之外,它实际上是否会影响生成的代码?它是否为如何使用该类型添加了任何约束?
希望看到一个真实的例子来证明这一点。

0 投票
1 回答
1454 浏览

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+ 参数提供完全独立的代码。

0 投票
3 回答
4842 浏览

c++ - 在并行算法中使用 range::view::iota

由于在中没有基于索引的并行算法,我想知道是否可以结合使用来模拟它。那是:ranges::view::iotastd::for_each

iota_view似乎为适当的类型([range.iota.iterator])提供随机访问:

iota_view<I, Bound>::iterator::iterator_category定义如下:

(1.1) — 如果I模型Advanceable,那么iterator_categoryrandom_access_iterator_tag

(1.2) — 否则,如果I模型Decrementableiterator_category则为bidirectional_iterator_tag

(1.3) — 否则,如果I模型Incrementableiterator_category则为forward_iterator_tag

(1.4) — 否则,iterator_categoryinput_iterator_tag

上面的代码正确吗?iota_view使用这种方式是否有任何性能损失?


编辑:我用range-v3cmcstl2和 Intel 的PSTL做了一些测试。

使用 range-v3,上面的示例无法使用 GCC 8 编译。编译器抱怨beginend具有不同的类型:

使用 cmcstl2 代码可以干净地编译,但不能并行运行。在我看来,它回退到顺序版本,可能是因为不满足前向迭代器的要求(https://godbolt.org/z/yvr-M2)。

有一个有点相关的 PSTL 问题(https://github.com/intel/parallelstl/issues/22)。

0 投票
2 回答
5443 浏览

c++ - 在现代 C++ 中是否可以将字符串文字作为参数传递给 C++ 模板?

是否可以在“现代 C++”(C++17 或更高版本)中将字符串文字作为参数传递给 C++ 模板?

我意识到你可以用构造函数参数来做到这一点;我只是认为将它作为模板参数会更方便,而不是深埋在 cpp 文件中。我很好奇这是否是现代 C++ 的一个新特性。请参阅下面的伪代码,了解我正在尝试做的事情:

伪代码示例:

0 投票
1 回答
483 浏览

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::durationstd::chrono::duration<int64_t, std::nano>. 当我尝试std::chrono::duration_cast在这两个持续时间之间进行施法时,我在任一方向都被大量截断。在调试器中跟踪它,我发现它与duration_cast实现有关,它在 libstdc++、libc++ 和 boost::chrono 中以同样的方式失败。简而言之,要从 system 转换为 ntp 表示,它会乘以 8388608/1953125 的比率,并在另一个方向上乘以相反的比率。它首先乘以分子,然后除以分母。数学是正确的,但初始乘法会溢出 64 位表示并被截断,尽管实际转换(除法后)仍然很容易用这些位表示。

我可以手动进行此转换,但我的问题如下:

  1. 这是实现中的错误,还是只是一个限制?
  2. 如果有限制,我是否应该意识到这将是一个问题?我没有看到任何可能导致能够猜测这不起作用的文档。
  3. 是否有一种通用的方法来实现这一点,而不是同一个问题?
  4. 是否应该报告,向谁报告?
  5. 最后,如果当 C++20 出现时,我使用具有手动策划to_sysfrom_sys功能的 NTP 时钟,我是否能够简单地使用std::chrono::clock_cast而不必担心其他微妙的问题?

这是我用来测试的代码和一些示例输出:

样本输出:

0 投票
1 回答
517 浏览

c++ - 模块会成为 C++20 的一部分吗?它会减少库的编译时间吗?

嗨,我是具有 2.5 年经验的全职 c++ 程序员。我对 C++14 的新特性感觉很好。我每天都用它们。然而,每次我编译我的代码时,都会花费很多时间,甚至超过 15 分钟。我浏览了有关如何使用前向引用、预编译头文件等减少编译时间的指南。但是,即使对于我喜欢尝试一些逻辑/新功能或库的小型 c++ 项目,编译仍然需要很长时间。我很少读到关于没有进入 C++17 的模块。我只是想知道它会成为 C++20 的一部分吗?它会减少编译时间吗?如果是这样,会减少多少?

0 投票
1 回答
1807 浏览

c++ - Shouldn't `std::shared_ptr` use `std::default_delete` by default?

std::default_delete can be specialized to allow std::unique_ptrs 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++:

  1. Create it managed by a shared-pointer, using std::make_shared or std::allocate_shared. This is the preferred way, as it coalesces both memory-blocks needed (payload and reference-counts) into one. Though iff there are only std::weak_ptrs left, the need for the reference-counts will by necessity still pin down the memory for the payload too.

  2. 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 expression delete[] p, when T is an array type, or delete p, when T is not an array type, shall have well-defined behavior, and shall not throw exceptions.
5 Effects: When T is not an Array type, constructs a shared_ptr object that owns the pointer p. Otherwise, constructs a shared_ptr that owns p and a deleter of an unspecified type that calls delete[] p. When T is not an array type, enables shared_from_this with p. If an exception is thrown, delete p is called when T 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:

  1. Is there a, preferably good, reason that it is not specified to use std::default_delete instead?
  2. Would any valid (and potentially useful?) code be broken by that change?
  3. Is there already a proposal to do so?
0 投票
1 回答
402 浏览

c++ - 现代 C++ 会支持 C#“Object Initalizer”语法吗?

我很好奇现代 c++ 标准人们是否考虑或添加了 C# 的“对象初始化器”语法。例如,在 C# 中,我可以在初始化期间像这样初始化对象的成员:

如果标准人们计划将“对象初始化器”语法添加到现代 C++ 中,那将非常方便,即。C++11、C++14、C++17、C++20等...

它目前是否存在于现代 C++ 规范中?

0 投票
2 回答
377 浏览

c++ - 使用概念启用类模板的成员函数

所以我有一个概念Fooable

而且我有一个Bar将类型T作为模板参数的类模板,并且我只想在以下情况下启用成员T函数Fooable

是否可以在 C++17 中使用概念 TS 或在 C++2a 中?

0 投票
2 回答
3387 浏览

c++ - 临时范围上的基于范围的 for 循环

由于 valgrind 中的一些分段错误和警告,我发现这段代码不正确,并且在 for-range 循环中有某种悬空引用。

看起来好像beginend是从一个临时的并且丢失在循环中的。

当然,一种解决方法是

但是,我想知道为什么for(auto e : f()[5])会出现错误,以及是否有更好的方法或某种设计方法,f甚至是容器(std::vector)来避免这种陷阱。

使用迭代器循环更清楚为什么会发生这个问题(begin并且end来自不同的临时对象)

但在 for-range 循环中,如第一个示例所示,似乎很容易犯此错误。