此代码可以正确编译并运行:
\n#include <ranges>\n#include <iostream>\n\nint main() {\n const auto r = std::views::iota(\'a\', static_cast<char>(\'g\' + 1));\n\n for(const auto& [start, end] : r | std::views::chunk(3u)) {\n for(auto it = start; it != end; ++it) {\n std::cout << *it << " ";\n }\n std::cout << "\\n";\n }\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n其输出为:
\na b c \nd e f \ng \nRun Code Online (Sandbox Code Playgroud)\n如果我将定义更改r如下:
a b c \nd e f \ng \nRun Code Online (Sandbox Code Playgroud)\n该代码无法编译。GCC 13 发出以下错误:
\nchunk.cpp:13:21: error: cannot decompose inaccessible …Run Code Online (Sandbox Code Playgroud) 在 C++23 中,lambda 表达式支持显式对象参数(也称为“推导 this”)。我在[expr.prim.lambda]/p5处捕获时发现了 lambda 的奇怪限制。
给定具有 lambda 捕获的 lambda,lambda 函数调用运算符(可能从函数调用运算符模板实例化)的显式对象参数(如果有)的类型应为:
- 闭合类型,
- 从闭包类型派生的类类型,或者
- 对可能符合 cv 资格的此类类型的引用。
[示例2:
Run Code Online (Sandbox Code Playgroud)struct C { template <typename T> C(T); }; void func(int i) { int x = [=](this auto&&) { return i; }(); // OK int y = [=](this C) { return i; }(); // error int z = [](this C) { return 42; }(); // OK }--结束示例]
问题:为什么仅使用 capture 的 lambda 有这样的限制?是否存在执行问题?
使用 C++23,我们可以漂亮地打印范围,目前在{fmt}. 例如,std::set格式为{},而序列容器如std::vector格式为[]。在内部,formatter类模板根据嵌套 typedef 的存在key_type(std::set有或std::vector没有)进行调度。
通过管道将 astd::set插入任何类型view都会删除key_typetypedef 并将其漂亮地打印为std::vector.
#include <ranges>
#include <set>
#include <fmt/ranges.h>
int main()
{
auto s = std::set<int>({ 2, 3, 5, 7 });
fmt::println("{}", s); // nice, formats as { 2, 3, 5, 7 }
fmt::println("{}", s | std::views::reverse); // meh, now uses [] instead of {}
fmt::println("{}", s | std::views::reverse …Run Code Online (Sandbox Code Playgroud) P0847提出了对成员函数使用显式参数的可能性this。
除了该提案带来的其他好处之外,CRTP 还为没有 C、R 甚至 T 的 CRTP带来了巨大的新可能性。
在 C++ 中实现泛型的常见做法clone是基于 CRTP,例如请参阅此 SO 帖子。
鉴于我们需要clone(virtual或者至少表现为虚拟),允许:
Shape* pCopy = pShape->clone(); // get a copy of the correct runtime type
Run Code Online (Sandbox Code Playgroud)
并且鉴于建议不应声明具有显式 this 参数的成员函数virtual。
是否仍然有办法使用 P0847 来实现具有动态行为且无需 CRTP 的通用克隆?
根据https://en.cppreference.com/w/cpp/ranges/split_view,std::ranges::split_view自 C++20 起必须可用。然而,同一页面上的示例在其文本中包含“C++23”:
#include <iostream>
#include <iomanip>
#include <ranges>
#include <string_view>
int main() {
constexpr std::string_view words{"Hello-_-C++-_-23-_-!"};
constexpr std::string_view delim{"-_-"};
for (const std::string_view word : std::ranges::split_view(words, delim)) {
std::cout << std::quoted(word) << ' ';
}
}
Run Code Online (Sandbox Code Playgroud)
GCC 和 MSVC 都拒绝接受 C++20 模式下的这个示例。MSVC 特别打印:
The contents of <ranges> are available only in c++latest mode with concepts support;
Run Code Online (Sandbox Code Playgroud)
https://gcc.godbolt.org/z/4fGGb3aqY
-std=c++2bGCC 开始使用命令行开关接受代码(意味着即将推出的 C++23),而 MSVC 即使使用/std:c++latest选项也会报告错误
error C2440: 'initializing': cannot convert from 'std::ranges::split_view<std::basic_string_view<char,std::char_traits<char>>,std::basic_string_view<char,std::char_traits<char>>>::_Outer_iter<true>::value_type' to 'std::basic_string_view<char,std::char_traits<char>>'
note: No …Run Code Online (Sandbox Code Playgroud) 我使用以下代码来打印通用 C++ 容器并排除字符串(感谢这个SO 答案)。
#include <iostream>
#include <vector>
template <typename T,
template <typename ELEM, typename ALLOC = std::allocator<ELEM>>
class Container>
std::ostream &operator<<(std::ostream &out, const Container<T> &container) {
out << "[";
bool first = true;
for (const auto &elem : container) {
if (first)
first = false;
else
out << ", ";
out << elem;
}
return out << "]";
}
int main() {
std::vector<std::vector<int>> v{{1, 2}, {3, 4}};
std::cout << v << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
哪个正确打印二维向量
[[1, …Run Code Online (Sandbox Code Playgroud) 我经常摆弄循环,它们几乎是相同的,我认为如果你有一个模板,你可以简化很多代码。
// the blocks can be different, but the number is known before compilation
const int block_1 = 10,
block_2 = 4,
block_3 = 6,
block_4 = 3;
Run Code Online (Sandbox Code Playgroud)
基本上所有的循环都是这样
循环可以是这样的
for (int i = 1; i < block_1 - 1; ++i) {
}
Run Code Online (Sandbox Code Playgroud)
或这个
for (int i = 1; i < block_1 - 1; ++i) {
for (int k = 1; k < block_2 - 1; ++k) {
}
}
Run Code Online (Sandbox Code Playgroud)
或这个
for (int i = 1; i < block_1 - …Run Code Online (Sandbox Code Playgroud) 归结为:
#include <memory>
class dummy;
std::unique_ptr<dummy> test;
class dummy {
};
Run Code Online (Sandbox Code Playgroud)
当使用 clang++-14 和 c++2b 编译时:
它简要给出:
clang++ ../bugl.cpp -I /usr/lib/llvm-14/include -std=c++2b
In file included from ../bugl.cpp:1:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/memory:76:
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/unique_ptr.h:93:16: error: invalid application of 'sizeof' to an incomplete type 'dummy'
static_assert(sizeof(_Tp)>0,
^~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/unique_ptr.h:396:4: note: in instantiation of member function 'std::default_delete<dummy>::operator()' requested here
get_deleter()(std::move(__ptr));
^
../bugl.cpp:4:24: note: in instantiation of member function 'std::unique_ptr<dummy>::~unique_ptr' requested here
std::unique_ptr<dummy> test;
^
../bugl.cpp:2:7: note: forward declaration of 'dummy'
class dummy;
^
1 …Run Code Online (Sandbox Code Playgroud) std::print() 将在 C++23 中添加。
我想知道是否std::print()是线程安全的,因为没有数据竞争
它是否存在文本交错问题,例如,如果我在线程 1 中存在:
std::print("The quick brown fox ")
std::print("jump over the lazy dog \n")
Run Code Online (Sandbox Code Playgroud)
和线程 2:
std::print("She sells ")
std::print("seashells by the seashore \n")
Run Code Online (Sandbox Code Playgroud)
它会以疯狂的顺序打印吗,就像这样:
She sells The quick brown fox seashells by the seashore \n
jump over the lazy dog \n
Run Code Online (Sandbox Code Playgroud)
我想这两个问题的答案都是肯定的,与 的行为相匹配std::cout,但是任何人都可以将我与标准所说的联系起来吗?
C++23 引入了范围视图std::generator,用作协程的返回。根据以前的观点,通常很难生成复杂的数据序列。我认为使用协程可以大大简化这一过程。
不幸的std::generator是,目前没有任何标准库实现,并且在许多项目中,C++20 将在一段时间内保持标准。std::generator有没有办法在C++20项目中使用?