标签: c++23

理解 C++23 中的 std::inout_ptr 和 std::out_ptr

我一直在阅读为 C++23 提出的库更改列表,我对std::out_ptrand std::inout_ptr(他们的_t兄弟姐妹)很好奇。据我所知,它们是智能指针与原始指针兼容的某种包装,但我还没有设法理解它们。也许这里有人熟悉该提案,或者可能会给出不太像ISO 的解释或示例?

c++ pointers c++23

6
推荐指数
1
解决办法
126
查看次数

如何使用 GCC 12.1 生成 C++23 堆栈跟踪?

在GCC12 的发行说明中,“运行时库 (libstdc++) ”部分下写道:

改进了实验性 C++23 支持,包括:[...] <stacktrace>(默认情况下未构建,需要链接到额外的库)。

我需要链接哪个库才能使用<stacktrace>?我使用的是 x86 Linux 系统,如果这很重要的话。

c++ linux g++ c++23

6
推荐指数
1
解决办法
1981
查看次数

在 C++23 中,仍然无法使用 value_type/reference 为pair的代理迭代器对范围进行排序吗?

尽管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++ std-ranges c++23

6
推荐指数
1
解决办法
211
查看次数

C++ 23 std::print 或 std::println 是否刷新输出流?

在 C++ 23 之前,当使用std::cout将输出发送到时stdout,以下两种在打印字符串末尾添加新行的方法之间存在区别:

  • std::cout << "Hello World\n";
  • std::cout << "Hello World" << std::endl;

其中第二个通常更可取,因为它会导致输出流刷新,而不是需要调用std::cout.flush().

在 C++ 23 中,现在有两个新的打印函数以及标准库的新组件。我们有std::printstd::println

在刷新输出流时,这些函数是否有区别?

或者,刷新输出流是否不再是这些新实现中相关的概念?

文档中cppreference没有提到冲洗:

c++ stl fmt c++23

6
推荐指数
1
解决办法
2727
查看次数

C++23 中是否有支持 const/ref/noexcept 的可复制函数包装器?

C++23 引入了对隐式参数和函数本身的std::move_only_function支持。constl/r-value-referencethisnoexcept(true/false)

\n

旧的std::function缺乏这些超载。

\n
#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)

c++ c++23

6
推荐指数
1
解决办法
359
查看次数

不能将运算符 &lt;&lt; 与 std::float128_t 一起使用;我该如何打印它?

我有以下代码,无法使用 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 特性 文件) …

c++ iostream x86-64 c++23 stdfloat

6
推荐指数
1
解决办法
910
查看次数

内联函数出现在 std::stacktrace 中,但 main 没有出现

我有以下代码:

#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)

c++ gcc stack-trace c++23

6
推荐指数
1
解决办法
360
查看次数

字节数组的放置新(隐式创建对象)是否会结束先前占用该存储的对象的生命周期?

P0593,在类型双关部分下,展示了这个例子:

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)]理论上可以改变 …

c++ lifetime placement-new language-lawyer c++23

6
推荐指数
1
解决办法
147
查看次数

就特定视图的使用而言,std::ranges::algorithm 与基于范围的 for() 循环相比在语义上有所不同

我想逐列查看 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)

c++ for-loop std-ranges c++23

6
推荐指数
1
解决办法
301
查看次数

具有不完整类型的 lambda 函数

以下代码可以正常编译:

\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};\n
Run 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};\n
Run 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\n
Run Code Online (Sandbox Code Playgroud)\n

所以基本上我有两个不同的问题,因为我不明白这里发生了什么。

\n
    \n
  1. 为什么在第一种情况下允许使用不完整类型?
  2. \n …

c++ c++23

6
推荐指数
1
解决办法
219
查看次数