标签: c++23

错误:“to”不是“std::ranges”的成员

面临问题 std::ranges::to我正在执行https://en.cppreference.com/w/cpp/ranges/to 中的以下示例

#include <algorithm>
#include <concepts>
#include <iostream>
#include <ranges>
#include <vector>
 
int main()
{
    auto vec = std::views::iota(1, 5)
             | std::views::transform([](auto const v){ return v * 2; })
             | std::ranges::to<std::vector>();
 
    static_assert(std::same_as<decltype(vec), std::vector<int>>);
 
    std::ranges::for_each(vec, [](auto const v){ std::cout << v << ' '; });
}
Run Code Online (Sandbox Code Playgroud)

但出现错误

main.cpp: In function 'int main()':
main.cpp:11:29: error: 'to' is not a member of 'std::ranges'
   11 |              | std::ranges::to<std::vector>();
      |                             ^~
main.cpp:11:43: error: missing template arguments before '>' token
   11 |              | std::ranges::to<std::vector>(); …
Run Code Online (Sandbox Code Playgroud)

c++ c++23

5
推荐指数
1
解决办法
1512
查看次数

C++23 多线程应用程序中的 std::start_lifetime_as 和 UB

假设X和是适合这种用途的类型,那么在一个线程中的内存区域上Y使用作为一种类型并在另一个线程中的完全相同的内存上使用是否是UB?标准对此有什么规定吗?如果不正确,正确的解释是什么?std::start_lifetime_as<X>std::start_lifetime_as<Y>

c++ object-lifetime undefined-behavior language-lawyer c++23

5
推荐指数
2
解决办法
503
查看次数

为什么编译器无法自动匹配范围基 for 循环中“size_t”变量的类型?

我偶然发现了与range一起operator<<使用时存在不明确重载的问题。\n更具体地说,使用以下代码:std::views::enumeratesize_t

\n
#include <iostream>\n#include <ranges>\nnamespace rv = std::ranges::views;\n\nint main()\n{\n    for (const auto& [idx, value] : rv::iota(0zu, 5zu) | rv::enumerate)\n        std::cout << idx << '\\n';\n}\n
Run Code Online (Sandbox Code Playgroud)\n

gcc 13.1.1在 Linux 上使用以下命令进行编译:g++ --std=c++23 main.cpp.\n我收到错误:

\n
main.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\nmain.cpp:11:19: error: ambiguous overload for \xe2\x80\x98operator<<\xe2\x80\x99 (operand types are \xe2\x80\x98std::ostream\xe2\x80\x99 {aka \xe2\x80\x98std::basic_ostream<char>\xe2\x80\x99} and \xe2\x80\x98std::tuple_element<0, const std::tuple<__int128, long unsigned int> >::type\xe2\x80\x99 {aka \xe2\x80\x98const __int128\xe2\x80\x99})\n   11 |         std::cout << idx << '\\n';\n      |         ~~~~~~~~~ ^~ ~\n      |              | …
Run Code Online (Sandbox Code Playgroud)

c++ implicit-conversion std-ranges c++23

5
推荐指数
1
解决办法
220
查看次数

c++23 断不动吗

标准中有关隐式移动的措辞在 c++23 中发生了变化,
请参阅https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2266r3.html
相关部分是:

返回的符合移动条件的 id 表达式始终是 xvalue

这似乎打破了流行但不明智的“不动”

template<typename T>
auto unmove(T&& v) -> std::remove_reference_t<T>& { return v; }
Run Code Online (Sandbox Code Playgroud)

当前的实现似乎同意:https ://godbolt.org/z/3n39rGM7b

这个重大改变是有意为之的,还是我们可以期待灾难恢复?

c++ language-lawyer c++23

5
推荐指数
1
解决办法
196
查看次数

为什么 GCC 不能通过别名优化构造函数调用?

受到这个问题的启发

有了这个代码

#include <string>

template<class T>
struct A {
    template <typename U> using NewA = A<U>;
    constexpr A(T const& t){}
    constexpr auto f() const {
        return NewA{"bye"};
    }
};

A(const char*) -> A<std::string>;

int main() {
    A{"hello"}.f();
}
Run Code Online (Sandbox Code Playgroud)

GCC 13.1 生成大量无用代码(最显着的是调用 std::string 构造函数/析构函数以及其他一些东西)

main:
        sub     rsp, 72
        mov     edx, OFFSET FLAT:.LC1+5
        mov     esi, OFFSET FLAT:.LC1
        lea     rax, [rsp+16]
        mov     rdi, rsp
        mov     QWORD PTR [rsp], rax
        call    void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) [clone .isra.0] …
Run Code Online (Sandbox Code Playgroud)

c++ c++23

5
推荐指数
1
解决办法
167
查看次数

std::ranges::views::enumerate 在 GCC 上建立索引时是否使用了错误的类型?

首先,使用 Range-v3,我注意到

std::vector<int> v;
auto w = v | ranges::views::enumerate;
auto [x, y] = *w.begin();
static_assert(std::is_same_v<std::size_t, decltype(x)>);
Run Code Online (Sandbox Code Playgroud)

这对我来说很有意义,因为std::size_t据我所知,这是用于索引对象的正确类型

然后,对于 C++20 范围,静态断言会失败。相反,以下传递,

static_assert(std::is_same_v<long, decltype(x)>);
Run Code Online (Sandbox Code Playgroud)

但与我的系统上long的不一样,我在其中验证了这一点std::size_t

static_assert(std::is_same_v<unsigned long, std::size_t>)
Run Code Online (Sandbox Code Playgroud)

在 GCC 13.2.1 上,这是示例

c++ size-t language-lawyer std-ranges c++23

5
推荐指数
1
解决办法
209
查看次数

std::可选::使用 std::addressof 进行变换

考虑以下代码:

#include <memory>
#include <optional>

template <typename T>
constexpr T * arg_to_pointer(T & arg) noexcept {
    return std::addressof(arg);
}

int main() {
    std::optional<int> foo;

    auto * test = foo.transform(arg_to_pointer<int>).value_or(nullptr);
    //auto * test = foo.transform(std::addressof<int>).value_or(nullptr);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

未注释掉的行(将一个哑包装器std::addressof作为函数参数传递给std::optional::transform)可以编译并正常工作。被注释掉的行(尝试std::addressof直接使用的行)没有 - 我收到一条错误,指示模板参数推导失败(此处使用 GCC 13.2 的实时示例,尽管在 Clang 16.0 中观察到类似的行为)。为什么是这样?std::addressof标准和我周围的愚蠢包装有什么区别?

c++ stdoptional c++23

5
推荐指数
1
解决办法
138
查看次数

具有显式对象参数和 std::invoke_result_t 的 Lambda

如何获取具有使用推导此签名的 lambda 的返回类型std::invoke_result_t

auto lambda = [](this auto& self, int x) -> int {
    return x;
};  
  
auto x = std::invoke_result_t<decltype(lambda), int>{}; //won't compile
Run Code Online (Sandbox Code Playgroud)

我是否需要以某种方式指定 self 参数std::invoke_result_t

我尝试过没有“推导这一点”,并且上面的示例有效。

编辑: 编译器资源管理器链接

c++ lambda type-deduction c++23 explicit-object-parameter

5
推荐指数
1
解决办法
162
查看次数

如何使用 CMake 执行“导入 std”

根据thisCMake 3.28,我们应该能够import std 无需任何额外的努力。但我在下面的简单演示中遇到了错误Module 'std' not found

import std;

int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
cmake_minimum_required(VERSION 3.28)
project(module_tst)

set(CMAKE_CXX_STANDARD 23)

add_executable(demo)
target_sources(demo
    PRIVATE
    main.cpp
)
Run Code Online (Sandbox Code Playgroud)

import std只要我检查了C/C++ -> General -> Scan Sources for Module Dependencies. 我在 cmake 文档中发现了类似的内容,CXX_SCAN_FOR_MODULES但将其设置为没有任何区别。有什么遗漏吗?

我正在使用最新的 cmake 3.28 rc1 和 VS 17.8.0 Preview 4.0

c++ cmake c++23

5
推荐指数
1
解决办法
574
查看次数

如何为 std::ranges::to 启用我的类型?

如何使用转换为自定义数据结构std::ranges::to

基本上是这样的

struct my_data {
   char b;
   int foo;
   std::string baz;
};

auto text = "v 3 fool|x 56 description|e 123 name"sv;

auto converted = text | std::views::split('|') 
               | std::views::transform([](auto r) { 
                   return r | std::ranges::to<my_data>();
               }) | std::ranges::to<std::vector>();
// converted should be a vector<my_data>
Run Code Online (Sandbox Code Playgroud)

需要什么样的东西my_data才能使用它进行转换std::ranges::to

c++ std-ranges c++23

5
推荐指数
1
解决办法
197
查看次数