前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 中文周刊 第127期

C++ 中文周刊 第127期

作者头像
王很水
发布2024-07-30 14:21:08
640
发布2024-07-30 14:21:08
举报
文章被收录于专栏:C++ 动态新闻推送

资讯

标准委员会动态/ide/编译器信息放在这里

编译器信息最新动态推荐关注hellogcc公众号 本周更新 2023-08-16 第215期 [1]

boost 1.8.3发布,最后一个支持c++03的版本

https://www.boost.org/users/history/version_1_83_0.html

重点发布就是boost::concurrent_flat_map

代码语言:javascript
复制
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 [2]
代码语言:javascript
复制
int main() {
    auto i = 42;
    std::cout << std::format("{:#018X}", reinterpret_cast<uintptr_t>(&i)); // prints 0X00007FFD9D71776C
}

有点用,但也不是很多

模板元编程的精妙之--2/16进制字面量转换为编译期字符串 [3]
代码语言:javascript
复制
  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[4]

shared_ptr有额外的计数信息, 大概这样

代码语言:javascript
复制
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[5]

讲智能指针的内存布局

shared_ptr是有额外的信息的,这部分信息需要一个分配

代码语言:javascript
复制
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[6]

enable_shared_from_this怎么实现的?大概思路就是weak_ptr

代码语言:javascript
复制
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拉

代码语言:javascript
复制
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就行了,类似这样

代码语言:javascript
复制
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[7]

编译器还没加上这个能力,可以用这个体验 https://github.com/kokkos/mdspan,在线 https://godbolt.org/z/Mxa7cej1a

之前也讲过很多次了,直接贴代码吧

代码语言:javascript
复制
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[8]

SIMD时间

常规

代码语言:javascript
复制
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

代码语言:javascript
复制
__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[9]

range的坑,没有完全零开销,需要拷贝

Writing custom C++20 coroutine systems[10]

手把手教你写协程

Parameter Passing in Flux versus Ranges[11]

他也写了个range库 flux,对比了一下和range的差异,优缺点

How to convert an enum to string in C++[12]

推荐使用magic_enum

视频

CppNow基本上一周出几个视频,列个有意思的

The New C++ Library: Strong Library Foundation for Future Projects - Jonathan Müller & Arno Schödl [13]

ppt在这里 https://www.jonathanmueller.dev/talk/think-cell-library/

代码在这里 https://github.com/think-cell/think-cell-library

非常通用的组件介绍

比如std::exchange

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
void tc::optional<T>::reset() {
    if (_has_value) {
        _has_value = false;
        value().~T();
    }
}

使用tc::change

代码语言:javascript
复制
void tc::optional<T>::reset() {
    if (tc::change(_has_value, false)) {
        value().~T();
    }
}

为啥为了省一个if这么麻烦?,举个例子,异常+重入

代码语言:javascript
复制
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[14] 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群384042845和作者对线
  • • Unilang[15] deepin的一个通用编程语言,点子有点意思,也缺人,感兴趣的可以github讨论区或者deepin论坛看一看。这里也挂着长期推荐了
  • • gcc-mcf[16] 懂的都懂

工作招聘

有没有数据库相关的工作推荐我一下,我要失业了快(能远程更好)

本文永久链接[17]

如果有疑问评论最好在上面链接到评论区里评论,这样方便搜索,微信公众号有点封闭/知乎吞评论

引用链接

[1] 编译器信息最新动态推荐关注hellogcc公众号 本周更新 2023-08-16 第215期 : https://github.com/hellogcc/osdt-weekly/blob/master/weekly-2023/2023-01-04.md [2] 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 [3] 模板元编程的精妙之--2/16进制字面量转换为编译期字符串 : http://www.purecpp.cn/detail?id=2375 [4] Inside STL: Smart pointers: https://devblogs.microsoft.com/oldnewthing/20230814-00/?p=108597 [5] Inside STL: The shared_ptr constructor vs make_shared: https://devblogs.microsoft.com/oldnewthing/20230815-00/?p=108602 [6] Inside STL: The shared_ptr constructor and enable_shared_from_this: https://devblogs.microsoft.com/oldnewthing/20230816-00/?p=108608 [7] C++23: mdspan: https://www.sandordargo.com/blog/2023/08/15/cpp23-mdspan-mdsarray [8] 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/ [9] Some C++20 ranges aren’t const-iterable: https://quuxplusone.github.io/blog/2023/08/13/non-const-iterable-ranges/ [10] Writing custom C++20 coroutine systems: https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/coroutines-c++20/ [11] Parameter Passing in Flux versus Ranges: https://tristanbrindle.com/posts/parameter-passing-in-flux-vs-ranges [12] 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/ [13] The New C++ Library: Strong Library Foundation for Future Projects - Jonathan Müller & Arno Schödl : https://www.youtube.com/channel/UCxHAlbZQNFU2LgEtiqd2Maw [14] asteria: https://github.com/lhmouse/asteria [15] Unilang: https://github.com/linuxdeepin/unilang [16] gcc-mcf: https://gcc-mcf.lhmouse.com/ [17] 本文永久链接: https://wanghenshui.github.io/cppweeklynews/posts/127.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CPP每周推送 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 资讯
  • 文章
    • Did you know that C++26 std.format added formatting pointers ability [2]
      • 模板元编程的精妙之--2/16进制字面量转换为编译期字符串 [3]
        • Inside STL: Smart pointers[4]
          • Inside STL: The shared_ptr constructor vs make_shared[5]
            • Inside STL: The shared_ptr constructor and enable_shared_from_this[6]
              • C++23: mdspan[7]
                • Transcoding UTF-8 strings to Latin 1 strings at 18 GB/s using AVX-512[8]
                  • Some C++20 ranges aren’t const-iterable[9]
                    • Writing custom C++20 coroutine systems[10]
                      • Parameter Passing in Flux versus Ranges[11]
                        • How to convert an enum to string in C++[12]
                        • 视频
                          • The New C++ Library: Strong Library Foundation for Future Projects - Jonathan Müller & Arno Schödl [13]
                          • 开源项目需要人手
                          • 工作招聘
                          • 有没有数据库相关的工作推荐我一下,我要失业了快(能远程更好)
                            • 引用链接
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档