我一直在阅读为 C++23 提出的库更改列表,我对std::out_ptrand std::inout_ptr(他们的_t兄弟姐妹)很好奇。据我所知,它们是智能指针与原始指针兼容的某种包装,但我还没有设法理解它们。也许这里有人熟悉该提案,或者可能会给出不太像ISO 的解释或示例?
在GCC12 的发行说明中,“运行时库 (libstdc++) ”部分下写道:
改进了实验性 C++23 支持,包括:[...] <stacktrace>(默认情况下未构建,需要链接到额外的库)。
我需要链接哪个库才能使用<stacktrace>?我使用的是 x86 Linux 系统,如果这很重要的话。
尽管P2321zip提供了、 和P2165common_reference之间的专业化,和类对象之间的兼容性使得和可以相互转换,但 的比较函数在[pairs.spec]中只有以下候选:pairtuplepairtupletuplepairpair
template<class T1, class T2>
constexpr common_comparison_category_t<...>
operator<=>(const pair<T1, T2>& x, const pair<T1, T2>& y);
Run Code Online (Sandbox Code Playgroud)
注意到这里只有两个模板参数,所以我们仍然无法比较两个不同的pairs,例如:
using value_type = pair<int , string >;
using reference = pair<int&, string&>;
value_type val = {1, "a"};
reference ref = val;
val < ref; // no match for 'operator<'
Run Code Online (Sandbox Code Playgroud)
pair这意味着使用as value_type/ 的代理迭代器reference始终无法满足这个sortable …
在 C++ 23 之前,当使用std::cout将输出发送到时stdout,以下两种在打印字符串末尾添加新行的方法之间存在区别:
std::cout << "Hello World\n";std::cout << "Hello World" << std::endl;其中第二个通常更可取,因为它会导致输出流刷新,而不是需要调用std::cout.flush().
在 C++ 23 中,现在有两个新的打印函数以及标准库的新组件。我们有std::print和std::println。
在刷新输出流时,这些函数是否有区别?
或者,刷新输出流是否不再是这些新实现中相关的概念?
文档中cppreference没有提到冲洗:
C++23 引入了对隐式参数和函数本身的std::move_only_function支持。constl/r-value-referencethisnoexcept(true/false)
旧的std::function缺乏这些超载。
#include <functional>\n\nint main(){\n std::function<void()>([]noexcept(true){}); // okay \xe2\x9c\x93\n std::function<void()>([]noexcept(false){}); // okay \xe2\x9c\x93\n std::function<void()noexcept>([]noexcept(true){}); // not supported\n std::function<void()noexcept>([]noexcept(false){}); // not supported\n\n std::move_only_function<void()>([]noexcept(true){}); // okay \xe2\x9c\x93\n std::move_only_function<void()>([]noexcept(false){}); // okay \xe2\x9c\x93\n std::move_only_function<void()noexcept>([]noexcept(true){}); // okay \xe2\x9c\x93\n std::move_only_function<void()noexcept>([]noexcept(false){}); // fails \xe2\x9c\x93\n\n std::function<void()>([i=0]{}); // okay \xe2\x9c\x93\n std::function<void()>([i=0]mutable{}); // okay \xe2\x9c\x93\n std::function<void()const>([i=0]{}); // not supported\n std::function<void()const>([i=0]mutable{}); // not supported\n\n std::move_only_function<void()>([i=0]{}); // okay \xe2\x9c\x93\n std::move_only_function<void()>([i=0]mutable{}); // okay \xe2\x9c\x93\n std::move_only_function<void()const>([i=0]{}); // okay \xe2\x9c\x93\n std::move_only_function<void()const>([i=0]mutable{}); // fails \xe2\x9c\x93\n}\n …Run Code Online (Sandbox Code Playgroud) 我有以下代码,无法使用 x86_64 GCC 13 进行编译:
#include <iostream>
#include <stdfloat>
int main() {
std::cout << std::float128_t{1} << '\n';
}
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误:
<source>: In function 'int main()':
<source>:5:15: error: ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'std::float128_t' {aka '_Float128'})
5 | std::cout << std::float128_t{1} << '\n';
| ~~~~~~~~~ ^~ ~~~~~~~~~~~~~
| | |
| | std::float128_t {aka _Float128}
| std::ostream {aka std::basic_ostream<char>}
Run Code Online (Sandbox Code Playgroud)
列出的不明确重载是:
operator<<(long)operator<<(unsigned long)operator<<(bool)令人惊讶的是,operator<<(float)其他浮点类型没有列出。
我检查了 C++23 的编译器支持页面,应该支持此功能:
| C++23 特性 | 文件) … |
|---|
我有以下代码:
#include <stacktrace>
#include <iostream>
void bar() {
for (const auto &entry : std::stacktrace::current()) {
std::cout << entry << '\n';
}
}
void foo() {
bar();
}
int main() {
foo();
}
Run Code Online (Sandbox Code Playgroud)
在调试版本中,这会打印出您所期望的内容:
bar() at /app/example.cpp:5
foo() at /app/example.cpp:11
main at /app/example.cpp:15
at :0
_start at :0
Run Code Online (Sandbox Code Playgroud)
然而,我并不完全确定这个无名at :0条目代表什么。真正令人困惑的一点是当我们启用优化时-O2:
bar() at /app/example.cpp:5
foo() at /app/example.cpp:11
at :0
_start at :0
Run Code Online (Sandbox Code Playgroud)
考虑到汇编输出,我不明白这个输出是如何可能的:
main:
sub rsp, 8
call bar()
xor eax, eax
add rsp, 8
ret …Run Code Online (Sandbox Code Playgroud) float do_bad_things(int n) {
alignof(int) alignof(float)
char buffer[max(sizeof(int), sizeof(float))];
*(int*)buffer = n; // #1
new (buffer) std::byte[sizeof(buffer)];
return *(float*)buffer; // #2
}
Run Code Online (Sandbox Code Playgroud)
并指出:
提议的规则将允许一个
int对象突然出现以使第 #1 行有效 [...],并且将允许一个float对象同样突然出现以使第 #2 行有效。然而,这些示例在提议的规则下仍然没有定义行为。原因是 [basic.life]p4 的结果:
本文档中赋予对象和引用的属性仅在给定对象或引用的生命周期内适用。
具体来说,对象所持有的值仅在其整个生命周期内保持稳定。
int当第 #1 行中的对象的生命周期结束时(当第 #2 行中的对象重用其存储时float),它的值就消失了。对称地,当创建 float 对象时,该对象具有不确定的值 ([dcl.init]p12),因此任何加载其值的尝试都会导致未定义的行为。
强调我的
该提案声称有问题的部分是float对象的(隐式)创建。但是上一行 ( new (buffer) std::byte[sizeof(buffer)]) 不是已经重用了存储(通过创建数组),结束了相关byte的生命周期吗?int据我了解,安置总是新的结束内存中创建新对象的对象的生命周期。
另外,这个评论说“新表达式不承诺保留存储中的字节。 ”这是否意味着new (buffer) std::byte[sizeof(buffer)]理论上可以改变 …
我想逐列查看 3x3 网格,所以我想我会std::views::stride像这样使用:
#include <array>
#include <iostream>
#include <ranges>
auto main() -> int {
auto grid = std::array<std::array<int, 3>, 3>{{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}};
namespace vs = std::views;
auto strideCount = grid.size();
auto allElements = grid | vs::join;
auto columns = vs::iota(0uz, strideCount)
| vs::transform([allElements, strideCount](auto n) {
return allElements
| vs::drop(n)
| vs::stride(strideCount);
});
for (auto&& column : columns) {
for (auto element : column) {
std::cout << element << ' …Run Code Online (Sandbox Code Playgroud) 以下代码可以正常编译:
\n#include <cstddef>\n\nstruct A {\n char a;\n static constexpr int off(void) { return offsetof(A, a); }\n static constexpr int (*off_p)(void) = off;\n};\nRun Code Online (Sandbox Code Playgroud)\n以下看似相似的代码\n仅使用 lambda 简称,但无法编译:
\n#include <cstddef>\n\nstruct A {\n char a;\n static constexpr int (*off_p)(void) =\n [](void) static constexpr ->int { return offsetof(A, a); };\n};\nRun Code Online (Sandbox Code Playgroud)\n$ g++ -std=c++23 bad.cpp \nIn file included from /usr/include/c++/13/cstddef:50,\n from bad.cpp:1:\nbad.cpp: In static member function \xe2\x80\x98A::<lambda()> static\xe2\x80\x99:\nbad.cpp:5:74: error: invalid use of incomplete type \xe2\x80\x98struct A\xe2\x80\x99\nRun Code Online (Sandbox Code Playgroud)\n所以基本上我有两个不同的问题,因为我不明白这里发生了什么。
\n