从reddit/hackernews/lobsters/meetingcpp摘抄一些c++动态。
每周更新
欢迎投稿,推荐或自荐文章/软件/资源等,请提交 issue
介绍了concept相比于rust traits的区别。不引入新的语法形式
主要是std::transform(std::execution::seq
带来的并行优势
代码在这里
github.com/fenbf/articles/cpp17/CSV%20Reader/csv_reader.cpp 串行
github.com/fenbf/articles/cpp17/CSV%20Reader/csv_reader_par.cpp -并行
icc也切到llvm后端了?投入llvm的开发越来越多,针对功能实现的抉择也就多了起来,好事
介绍异常的方方面面,值得了解一下 (或者永远不用异常)
介绍了一个复杂的例子,如何用模板模板参数来改善CRTP复杂性
2021了不会还有人不知道变参模板吧
#include <iostream>
using namespace std::literals;
template <typename ... Args>
void printSize(Args&& ... args){
std::cout << sizeof...(Args) << ' '; // (1)
std::cout << sizeof...(args) << '\n'; // (2)
}
int main() {
std::cout << '\n';
printSize(); // (3)
printSize("C string", "C++ string"s, 2011, true); // (4) 打印几?
std::cout << '\n';
}
clang++上 -std=c++2b
可用 不过也导致了一些问题,列出了问题的解决方案
介绍c++20带来的std::cmp_xx函数
比较二个整数
t
与u
的值。不同于内建比较运算符,负有符号整数始终比较小于(且不等于)无符号整数:该比较相对于有损整数转换是安全的。
-1 > 0u; // true
std::cmp_greater(-1, 0u); // false
cppnow 2021全放出来了。之前看了几个,陆陆续续看一看,只介绍我感兴趣的了
std::function不能处理move的场景
#include <functional>
#include <memory>
struct widget {
// ...
};
int main() {
std::function<void()> f = [w_ptr = std::make_unique<widget>()] {
...
};
}
直接报错,所以要有支持move的f,any_invocable诞生,以前叫move_function/ function_ref改成这个了
这里有个实现 https://github.com/ofats/any_invocable/blob/master/include/ofats/invocable.h
ppt https://cppnow.digital-medium.co.uk/wp-content/uploads/2021/05/tfoai.pdf
这个视频就是介绍这个的原理,我看早晚进标准里
回顾了一下各种写库技巧,从tag dispatch到enable_if 到concept
一个测试框架的基本功能
- 运行测试用例以及运行指定的测试用例
- 足够多的assert失败信息
- 方便调试
- 。。
对比googletest boost.test catch2 doctest
都是基于宏实现(gtest,btest,doctest),且集成困难(库的形式),要么就是编译慢(catch2)
这里介绍boostext.ut,一个不依赖宏的简单集成的测试框架
看代码
lconstexpr auto sum(auto... args) { return (0 + ... + args); }
import ut; // C++20 module
int main() {
"sum"_test = [] { // Running... sum
sum(1, 2) == 42_i; // sum.cpp:5:FAILED [ 3 == 42 ]
}; // tests: 1 | 1 failed
} // asserts: 1 | 0 passed | 1 failed
suite sums = [] {
"sum with no args"_test = [] { expect(sum() == 0_i); };
"sum with single arg"_test = [] { expect(sum(42) == 42_i); };
"sum with multiple args"_test = [] { expect(sum(1, 2) == 3_i); };
};
用的是用户定义字面量 UDL
后面就详细的解释ut的实现
struct test {
std::string_view name{}; // test case name
auto operator=(std::invocable auto test) -> void {
std::clog << "Running... " << name << '\n';
test();
}
};
[[nodiscard]] constexpr concepts::test auto operator""_test(
const char* name, std::size_t size) {
return test{.name = {name, size}};
}
然后就是operator ==的实现
后面不介绍了
还定义了很多UDL,比如 _i
还有expect和suite的实现,不展开了,设计思路很有意思,从UDL入手,确实眼前一亮,但是,没有MOCK功能
为啥不用内建的整型 — > 被各种整形提升未定义行为折磨,放弃了
解决方案,enum as integers,不匹配直接爱咋咋地
// unsigned
enum class ui8 : std::uint8_t { tag_to_prevent_mixing_other_enums };
enum class ui16: std::uint16_t{ tag_to_prevent_mixing_other_enums };
enum class ui32: std::uint32_t{ tag_to_prevent_mixing_other_enums };
enum class ui64: std::uint64_t{ tag_to_prevent_mixing_other_enums };
// signed
enum class si8 : std::int8_t { tag_to_prevent_mixing_other_enums };
enum class si16: std::int16_t{ tag_to_prevent_mixing_other_enums };
enum class si32: std::int32_t{ tag_to_prevent_mixing_other_enums };
enum class si64: std::int64_t{ tag_to_prevent_mixing_other_enums };
然后用UDL把值抠出来
inline namespace literals {
consteval
ui16 operator""_ui16(unsigned long long val) {
if (val <= std::numeric_limits<std::underlying_type_t<ui16>>::max())
{
return ui16(val);
} else {
throw "integral constant too large"; // trigger compile-time error
}
}
然后围绕这个设定,补充traits/concept/assert等等。具体不展开了,还是UDL
parsco 一个基于coroutine的parser combinator
GitHub actions to setup GCC/Clang/MinGW-w64 reddit网友nisnete 写了很多github action可以直接用,非常牛逼
- https://github.com/egor-tensin/setup-gcc
- https://github.com/egor-tensin/setup-clang
- https://github.com/egor-tensin/setup-mingw
- https://github.com/egor-tensin/vs-shell
- https://github.com/egor-tensin/build-boost
- https://github.com/egor-tensin/clang-format
slitter 这个allocator设计的用来检测错误的。可以了解一下设计,主要灵感来自这篇论文, backtrace-labs 是一个帮忙定位问题收集信息的公司
tilck A Tiny Linux-Compatible Kernel 可以学一下如何自己做个小linux
CPP20Coroutines手把手教你写generator