面临问题 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) 假设X和是适合这种用途的类型,那么在一个线程中的内存区域上Y使用作为一种类型并在另一个线程中的完全相同的内存上使用是否是UB?标准对此有什么规定吗?如果不正确,正确的解释是什么?std::start_lifetime_as<X>std::start_lifetime_as<Y>
c++ object-lifetime undefined-behavior language-lawyer c++23
我偶然发现了与range一起operator<<使用时存在不明确重载的问题。\n更具体地说,使用以下代码:std::views::enumeratesize_t
#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}\nRun Code Online (Sandbox Code Playgroud)\n并gcc 13.1.1在 Linux 上使用以下命令进行编译:g++ --std=c++23 main.cpp.\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++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
这个重大改变是有意为之的,还是我们可以期待灾难恢复?
受到这个问题的启发
有了这个代码
#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) 首先,使用 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 上,这是示例。
考虑以下代码:
#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标准和我周围的愚蠢包装有什么区别?
如何获取具有使用推导此签名的 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?
我尝试过没有“推导这一点”,并且上面的示例有效。
编辑: 编译器资源管理器链接
根据this和CMake 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
如何使用转换为自定义数据结构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?