我刚刚看到 C++ 23计划弃用std::aligned_storage
andstd::aligned_storage_t
以及std::aligned_union
。std::aligned_union_t
据我所知,在对齐存储中放置新对象并不是特别constexpr
友好,但这似乎不是完全丢弃该类型的好理由。这让我假设使用std::aligned_storage
和朋友还存在一些我不知道的其他基本问题。那会是什么?
是否有建议替代这些类型?
std::expected
在最受尊敬的 stackoverflow 答案之一中,我找到了模板类用法
的示例: What are coroutines in C++20?
同时我在 cppreference.com 上找不到任何关于此类的提及。你能解释一下它是什么吗?
从 C++11 开始,我们可以在编译时进行浮点数学运算。C++23 和 C++26 添加了constexpr
一些函数,但不是全部。
constexpr
一般来说,浮点数学很奇怪,因为结果并不完全准确。然而,constexpr
代码应该始终提供一致的结果。C++ 如何解决这个问题?
constexpr
浮点数学
是如何工作的?constexpr
,而其他功能则不然(例如std::nearbyint
)根据cppreference,gcc 和 clang 最近都完成了P1102R2(“ Down with ()!”)的实现,这意味着我们可以在 C++23 中更简洁地定义 lambda 表达式。
但是我发现它们与某种形式不一致:
auto l = []<auto> noexcept requires true {};
Run Code Online (Sandbox Code Playgroud)
clang 接受这种形式,而 gcc拒绝其语法。
我应该信任哪个编译器?这个 lambda 在 C++23 中是格式正确还是格式错误?
或许是迫于舆论压力,clang在我举报后的五天内迅速修复了49736。
再进一步尝试时,无意中发现gcc也拒绝了以下有效表单,这让我报告了99850,2周后修复。
auto l = []<auto> requires true -> void {};
Run Code Online (Sandbox Code Playgroud) 与基本类型 \xe2\x80\x93和\xe2\x80\x93 不同float
, C++23 中引入的新类型将始终是 IEEE 标准二进制浮点类型吗?double
long double
floatN_t
<stdfloat>
固定宽度浮点的 cppreference 页面确实提到了精度和指数位,这与 IEEE 标准相匹配。但该页面并未在任何地方明确提及 IEEE 标准。IEEE 兼容的浮点意味着,它们不仅应该具有相同的精度和指数位,而且该标准还列出了必须以符合标准的方式支持的许多操作。那么这些类型是否严格遵循这一点呢?
\n当std::views::split()
获取未命名的字符串文字作为模式时,它不会分割字符串,但可以很好地处理未命名的字符文字。
#include <iomanip>
#include <iostream>
#include <ranges>
#include <string>
#include <string_view>
int main(void)
{
using namespace std::literals;
// returns the original string (not splitted)
auto splittedWords1 = std::views::split("one:.:two:.:three", ":.:");
for (const auto word : splittedWords1)
std::cout << std::quoted(std::string_view(word));
std::cout << std::endl;
// returns the splitted string
auto splittedWords2 = std::views::split("one:.:two:.:three", ":.:"sv);
for (const auto word : splittedWords2)
std::cout << std::quoted(std::string_view(word));
std::cout << std::endl;
// returns the splitted string
auto splittedWords3 = std::views::split("one:two:three", ':');
for (const auto word : …
Run Code Online (Sandbox Code Playgroud) 在 C++23 中,该[[assume(expression)]]
属性使得如果表达式为false
,则行为未定义。例如:
int div(int x, int y) {
[[assume(y == 1)]];
return x / y;
}
Run Code Online (Sandbox Code Playgroud)
y
这会编译成与始终相同的代码1
。
div(int, int):
mov eax, edi
ret
Run Code Online (Sandbox Code Playgroud)
但是,如果存在另一级别的未定义行为,会发生什么情况?
int div(int x, int y) {
[[assume(x / 0 == 1)]];
return x / y;
}
Run Code Online (Sandbox Code Playgroud)
现在假设里面有UB,但是假设没有被评估。这是什么意思?这只是无稽之谈还是编译器可以用这个假设做任何事情?
我有以下代码:
#include <print>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3};
std::println("{}", v);
}
Run Code Online (Sandbox Code Playgroud)
在这产生的众多错误中,有(clang++ -std=c++23 -stdlib=libc++
,https://godbolt.org/z/3z9Tseh37):
[...]/format_arg_store.h:167:17: error: static assertion failed due to [...]
167 | static_assert(__arg != __arg_t::__none, "the supplied type is not formattable");
| ^~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
这让我很困惑,因为根据cppreference C++23 编译器支持页面,libc++ 支持std::println
并实现P2286: Formatting Ranges。
我做错了什么还是这是标准库错误?
灵感来源:为什么 std::aligned_storage 在 C++23 中被弃用以及使用什么替代?
\n链接的提案P1413R3
(不赞成使用std::aligned_storage
)表示:
\n\n使用
\naligned_*
调用未定义的行为(类型无法提供存储。)
这是指[intro.object]/3
:
\n\n如果在与N \xe2\x80\x9d 类型的 \xe2\x80\x9carray或N \xe2 \ 类型 \xe2\x80\x9carray 的另一个对象e关联的存储中创建了完整对象 ([expr.new]) x80\x9d ([cstddef.syn]),该数组为创建的对象提供存储,如果: ...
\nunsigned char
std\xe2\x80\x8b::\xe2\x80\x8bbyte
然后,该标准在一些定义中继续使用术语“提供存储”,但我没有看到它在任何地方说使用不同类型作为新放置的存储(无法“提供存储”)会导致 UB 。
\n那么,问题是:std::aligned_storage
当用于放置新时,是什么导致了UB?
(我最初的问题是关于“发生了什么_BitInt
?”但这是基于对某些 cppreference 页面的误读)。
C++23 标准草案的库简介第 16.2 节表示 C++ 支持 C 标准库。然而,对特定 C 标准的唯一引用是在 16.3 的脚注 (#141) 中。这是 2018 年 C 标准,其中没有提到_BitInt
. _BitInt
但我在 C 23 标准草案中找到了描述。
C++23 标准是否包含特定版本的 C 标准库?
c++ ×10
c++23 ×10
assumption ×1
c++-faq ×1
c++26 ×1
constexpr ×1
deprecated ×1
fmt ×1
lambda ×1
libc++ ×1
split ×1
standards ×1
std-expected ×1
std-ranges ×1
stdvector ×1