-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1532b5e
commit 00167d6
Showing
1 changed file
with
378 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,378 @@ | ||
--- | ||
layout: post | ||
title: 第127期 | ||
--- | ||
# C++ 中文周刊 第127期 | ||
|
||
|
||
[周刊项目地址](https://github.com/wanghenshui/cppweeklynews) | ||
|
||
公众号 | ||
|
||
<img src="https://wanghenshui.github.io/cppweeklynews/assets/code.png" alt="" width="30%"> | ||
|
||
|
||
|
||
RSS https://github.com/wanghenshui/cppweeklynews/releases.atom | ||
|
||
欢迎投稿,推荐或自荐文章/软件/资源等 | ||
|
||
请[提交 issue](https://github.com/wanghenshui/cppweeklynews/issues) | ||
|
||
内容不多 | ||
|
||
--- | ||
|
||
## 资讯 | ||
|
||
标准委员会动态/ide/编译器信息放在这里 | ||
|
||
[编译器信息最新动态推荐关注hellogcc公众号 本周更新 2023-08-16 第215期 ](https://github.com/hellogcc/osdt-weekly/blob/master/weekly-2023/2023-01-04.md) | ||
|
||
|
||
|
||
boost 1.8.3发布,最后一个支持c++03的版本 | ||
|
||
https://www.boost.org/users/history/version_1_83_0.html | ||
|
||
重点发布就是`boost::concurrent_flat_map` | ||
|
||
```txt | ||
Unordered: | ||
Major update. | ||
Added boost::concurrent_flat_map, a fast, thread-safe hashmap based on open addressing. | ||
Sped up iteration of open-addressing containers. | ||
In open-addressing containers, erase(iterator), which previously returned nothing, now returns a proxy object convertible to an iterator to the next element. This enables the typical it = c.erase(it) idiom without incurring any performance penalty when the returned proxy is not used. | ||
``` | ||
|
||
|
||
## 文章 | ||
|
||
#### [Did you know that C++26 std.format added formatting pointers ability ](https://github.com/tip-of-the-week/cpp/blob/master/tips/343.md) | ||
|
||
```cpp | ||
int main() { | ||
auto i = 42; | ||
std::cout << std::format("{:#018X}", reinterpret_cast<uintptr_t>(&i)); // prints 0X00007FFD9D71776C | ||
} | ||
``` | ||
|
||
有点用,但也不是很多 | ||
|
||
#### [模板元编程的精妙之--2/16进制字面量转换为编译期字符串 ](http://www.purecpp.cn/detail?id=2375) | ||
|
||
|
||
```cpp | ||
asio::const_buffer b5 = 0xaB_buf; | ||
ASIO_CHECK(b5.size() == 1); | ||
ASIO_CHECK(memcmp(b5.data(), "\xab", 1) == 0); | ||
|
||
asio::const_buffer b6 = 0xABcd_buf; | ||
ASIO_CHECK(b6.size() == 2); | ||
ASIO_CHECK(memcmp(b6.data(), "\xab\xcd", 2) == 0); | ||
|
||
asio::const_buffer b7 = 0x01ab01cd01ef01ba01dc01fe_buf; | ||
ASIO_CHECK(b7.size() == 12); | ||
ASIO_CHECK(memcmp(b7.data(), | ||
"\x01\xab\x01\xcd\x01\xef\x01\xba\x01\xdc\x01\xfe", 12) == 0); | ||
``` | ||
编译期hex转字符串。很妙 | ||
代码在这里 https://github.com/chriskohlhoff/asio/blob/master/asio/include/asio/buffer.hpp#L2743 | ||
#### [Inside STL: Smart pointers](https://devblogs.microsoft.com/oldnewthing/20230814-00/?p=108597) | ||
shared_ptr有额外的计数信息, 大概这样 | ||
```cpp | ||
struct control_block { | ||
virtual void Dispose() = 0; | ||
virtual void Delete() = 0; | ||
std::atomic<unsigned long> shareds; | ||
std::atomic<unsigned long> weaks; | ||
}; | ||
template<typename T> | ||
struct shared_ptr { | ||
T* object; | ||
control_block* control; | ||
}; | ||
template<typename T> | ||
struct weak_ptr { | ||
T* object; | ||
control_block* control; | ||
}; | ||
``` | ||
|
||
unique_ptr比较简单,就是指针+deleter,然后空基类优化(compressed_pair) | ||
|
||
#### [Inside STL: The shared_ptr constructor vs make_shared](https://devblogs.microsoft.com/oldnewthing/20230815-00/?p=108602) | ||
|
||
讲智能指针的内存布局 | ||
|
||
shared_ptr是有额外的信息的,这部分信息需要一个分配 | ||
|
||
```cpp | ||
auto p = std::shared_ptr<S>(new S()); | ||
auto p = std::make_shared<S>(); | ||
``` | ||
|
||
这两种构造,第一种,由于是接管,S的内存和shared_ptr内部信息不是连续的,这对局部性缓存是不友好的 | ||
|
||
#### [Inside STL: The shared_ptr constructor and enable_shared_from_this](https://devblogs.microsoft.com/oldnewthing/20230816-00/?p=108608) | ||
|
||
enable_shared_from_this怎么实现的?大概思路就是weak_ptr | ||
|
||
```c++ | ||
template<typename T> | ||
struct enable_shared_from_this { | ||
using esft_detector = enable_shared_from_this; | ||
std::weak_ptr<T> weak_this; | ||
|
||
std::weak_ptr<T> weak_from_this() | ||
{ return weak_this; } | ||
|
||
std::shared_ptr<T> shared_from_this() | ||
{ return weak_this.lock(); } | ||
|
||
}; | ||
``` | ||
|
||
weak_this由谁来赋值?肯定是shared_ptr拉 | ||
|
||
```cpp | ||
template<typename T, typename D> | ||
struct shared_ptr { | ||
shared_ptr(T* ptr) | ||
{ | ||
... do the usual stuff ... | ||
|
||
/* Here comes enable_shared_from_this magic */ | ||
if constexpr (supports_esft<T>::value) { | ||
using detector = T::esft_detector; | ||
ptr->detector::weak_this = *this; | ||
} | ||
} | ||
|
||
... other constructors and stuff ... | ||
}; | ||
|
||
``` | ||
|
||
只要enable_shared_from_this实现 esft_detector就行了,类似这样 | ||
|
||
```cpp | ||
template<typename T, typename = void> | ||
struct supports_esft : std::false_type {}; | ||
|
||
template<typename T> | ||
struct inline bool supports_esft<T, | ||
std::void_t<typename T::esft_detector>> | ||
: std::true_type {}; | ||
``` | ||
这样继承的类都有特化的shared_ptr构造 | ||
#### [C++23: mdspan](https://www.sandordargo.com/blog/2023/08/15/cpp23-mdspan-mdsarray) | ||
编译器还没加上这个能力,可以用这个体验 https://github.com/kokkos/mdspan,在线 https://godbolt.org/z/Mxa7cej1a | ||
之前也讲过很多次了,直接贴代码吧 | ||
```cpp | ||
std::array numbers {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; | ||
stdex::mdspan<int, stdex::extents<int, 2, 5>, stdex::layout_right> mdspanOfNumbers {numbers.data()}; | ||
for (size_t rowIndex=0; rowIndex < mdspanOfNumbers.extent(0); ++rowIndex) { | ||
for (size_t columnIndex=0; columnIndex < mdspanOfNumbers.extent(1); ++columnIndex) { | ||
std::cout << mdspanOfNumbers[rowIndex, columnIndex] << ' '; | ||
} | ||
std::cout << '\n'; | ||
} | ||
/* | ||
1 2 3 4 5 | ||
6 7 8 9 10 | ||
*/ | ||
std::array numbers {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; | ||
stdex::mdspan<int, stdex::extents<int, 2, 5>, stdex::layout_left> mdspanOfNumbers {numbers.data()}; | ||
for (size_t columnIndex=0; columnIndex < mdspanOfNumbers.extent(0); ++columnIndex) { | ||
for (size_t rowIndex=0; rowIndex < mdspanOfNumbers.extent(1); ++rowIndex) { | ||
std::cout << mdspanOfNumbers[columnIndex, rowIndex] << ' '; | ||
} | ||
std::cout << '\n'; | ||
} | ||
/* | ||
1 3 5 7 9 | ||
2 4 6 8 10 | ||
*/ | ||
``` | ||
#### [Transcoding UTF-8 strings to Latin 1 strings at 18 GB/s using AVX-512](https://lemire.me/blog/2023/08/12/transcoding-utf-8-strings-to-latin-1-strings-at-12-gb-s-using-avx-512/) | ||
|
||
SIMD时间 | ||
|
||
常规 | ||
|
||
```cpp | ||
uint8_t leading_byte = data[pos]; // leading byte | ||
if (leading_byte < 0b10000000) { | ||
*latin_output++ = leading_byte; | ||
pos++; | ||
} else if ((leading_byte & 0b11100000) == 0b11000000) { | ||
*latin_output++ = (leading_byte & 1) << 6 | (data[pos + 1]); | ||
pos += 2; | ||
} | ||
``` | ||
|
||
simd | ||
|
||
```cpp | ||
__m512i input = _mm512_loadu_si512((__m512i *)(buf + pos)); | ||
__mmask64 leading = _mm512_cmpge_epu8_mask(input, _mm512_set1_epi8(-64)); | ||
__mmask64 bit6 = _mm512_mask_test_epi8_mask(leading, input, _mm512_set1_epi8(1)); | ||
input = _mm512_mask_sub_epi8(input, (bit6<<1) | next_bit6, input, _mm512_set1_epi8(-64)); | ||
next_bit6 = bit6 >> 63; | ||
__mmask64 retain = ~leading; | ||
__m512i output = _mm512_maskz_compress_epi8(retain, input); | ||
int64_t written_out = _popcnt64(retain); | ||
__mmask64 store_mask = (1ULL << written_out) - 1; | ||
_mm512_mask_storeu_epi8((__m512i *)latin_output, store_mask, output); | ||
``` | ||
完整代码 https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/tree/master/2023/08/11 | ||
#### [Some C++20 ranges aren’t const-iterable](https://quuxplusone.github.io/blog/2023/08/13/non-const-iterable-ranges/) | ||
range的坑,没有完全零开销,需要拷贝 | ||
#### [Writing custom C++20 coroutine systems](https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/coroutines-c++20/) | ||
手把手教你写协程 | ||
#### [Parameter Passing in Flux versus Ranges](https://tristanbrindle.com/posts/parameter-passing-in-flux-vs-ranges) | ||
他也写了个range库 flux,对比了一下和range的差异,优缺点 | ||
#### [How to convert an enum to string in C++](https://mariusbancila.ro/blog/2023/08/17/how-to-convert-an-enum-to-string-in-cpp/) | ||
推荐使用magic_enum | ||
## 视频 | ||
CppNow基本上一周出几个视频,列个有意思的 | ||
#### [The New C++ Library: Strong Library Foundation for Future Projects - Jonathan Müller & Arno Schödl ](https://www.youtube.com/channel/UCxHAlbZQNFU2LgEtiqd2Maw) | ||
ppt在这里 https://www.jonathanmueller.dev/talk/think-cell-library/ | ||
代码在这里 https://github.com/think-cell/think-cell-library | ||
非常通用的组件介绍 | ||
比如std::exchange | ||
```cpp | ||
template <typename T> | ||
class my_smart_ptr { | ||
T* _ptr; | ||
public: | ||
my_smart_ptr(my_smart_ptr&& other) noexcept | ||
: _ptr(other._ptr) { | ||
other._ptr = nullptr; | ||
} | ||
}; | ||
``` | ||
|
||
用上exchange | ||
```cpp | ||
template <typename T> | ||
class my_smart_ptr { | ||
T* _ptr; | ||
public: | ||
my_smart_ptr(my_smart_ptr&& other) noexcept | ||
: _ptr(std::exchange(other._ptr, nullptr)) | ||
{} | ||
}; | ||
``` | ||
这种语义是upsert,不只指针,其他value也可以这样优化,代码干净 | ||
所以实现了tc::change | ||
```cpp | ||
void tc::optional<T>::reset() { | ||
if (_has_value) { | ||
_has_value = false; | ||
value().~T(); | ||
} | ||
} | ||
``` | ||
|
||
使用tc::change | ||
|
||
|
||
```cpp | ||
void tc::optional<T>::reset() { | ||
if (tc::change(_has_value, false)) { | ||
value().~T(); | ||
} | ||
} | ||
``` | ||
|
||
为啥为了省一个if这么麻烦?,举个例子,异常+重入 | ||
|
||
```cpp | ||
void foo1() { | ||
… | ||
if (dirty) { | ||
clean(); | ||
dirty = false; | ||
} | ||
… | ||
} | ||
|
||
void foo2() { | ||
… | ||
if (tc::change(dirty, false)) { | ||
try { | ||
clean(); | ||
} catch (...) { | ||
dirty = true; | ||
throw; | ||
} | ||
} | ||
… | ||
} | ||
``` | ||
|
||
foo2比foo1更健壮点,避免了同时clean的场景 | ||
|
||
假如多个线程都在clean,而clean时间较长,dirty更新不及时,就更新了多次 | ||
|
||
foo2就避免了这种情况 | ||
|
||
还有一些range string的就不列了,感兴趣的可以看看 | ||
|
||
## 开源项目需要人手 | ||
|
||
- [asteria](https://github.com/lhmouse/asteria) 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群384042845和作者对线 | ||
- [Unilang](https://github.com/linuxdeepin/unilang) deepin的一个通用编程语言,点子有点意思,也缺人,感兴趣的可以github讨论区或者deepin论坛看一看。这里也挂着长期推荐了 | ||
- [gcc-mcf](https://gcc-mcf.lhmouse.com/) 懂的都懂 | ||
|
||
|
||
|
||
## 工作招聘 | ||
|
||
有没有数据库相关的工作推荐我一下,我要失业了快(能远程更好) | ||
--- | ||
|
||
|
||
|
||
[本文永久链接](https://wanghenshui.github.io/cppweeklynews/posts/127.html) | ||
|
||
如果有疑问评论最好在上面链接到评论区里评论,这样方便搜索,微信公众号有点封闭/知乎吞评论 |