C++ 中文周刊 2024-05-25 第158期

周刊项目地址

公众号

qq群 点击进入

RSS https://github.com/wanghenshui/cppweeklynews/releases.atom

欢迎投稿,推荐或自荐文章/软件/资源等,评论区留言

本期文章由 HNY 赞助, 本期内容很少


资讯

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

五月邮件

基本就是range constract executor 相关提案乱炖

讲几个R0

简单来说就是针对类级别的更精细的内存控制

operator new(sizeof(T), type_identity<T>{}, args)

通常这种都是自己搞个数组placement new

提供根据类型的new接口,能更简单实现这种逻辑。看一乐,提供一种思路

这个其实就是很多指针实际上更多是抽象的,可以利用bit做事,但标准对这块不是很清晰,算是UB吧

比如llvm的PointerIntPair arm的MTE hash trie的指针管理 或者pointer swizzle技巧那种把指针搞出复合语义

这种玩意其实就是tag pointer,不同tag表达不同含义,感觉标准化会更好一些

浮点数的min/max处理了太多边角场景(NaN之类的),不够快,不想用ffastmath情况下提供了一套新接口

帮你把optional variant any里的T掏出来。这个很干净

实现godbolt

帮P2786加了个接口实现P1144相同能力。看不懂?没事我也不懂

编译器信息最新动态推荐关注hellogcc公众号 本周更新 2024-0522第255期

文章

超好用的 C++ 在线编译器(VSCode 版)

godbolt集成vscode了,挺好的

C++神秘学习——memcpy的一个ub

memcpy data()了,编译器假设不空优化导致asan报错

vector string当buffer没问题,都用他们当buffer不用他们的成员函数复制是怎么个意思,瞧不起assign?

这个也和群友激烈讨论了

笔者的个人观点,data()虽然不是const,但是最好最好不乱玩,能用成员用成员,实在不行才hack,比如resize这种

assign肯定也是memcpy,他会帮你判断的,你直接拿来用,那肯定说明不为空,那编译器的假设笔者认为没毛病

write()和mmap写混用与cache alias

学到了

SLUB 分配器的下一步计划

看一乐

C++无锁(lock free)数据结构与有锁数据结构相比,速度,性能等有何区别?多线程中如何选择?

看一乐

long double to_string会丢失精度?

#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
    long double d = -20704.000055577169;
    string s = to_string(d);
    cout << s << endl;//-20704.000056 
    cout << setprecision(12) << fixed << s << endl;
}

两个输出没有差别。注意这个坑 godbolt

Looking up a C++ Hash Table with a pre-known hash

如果你知道了hash,如何避免容器计算hash?定制Equal,把hash比较也放进去,直接看完整代码

template<typename Hash>
class KeyHashPair {
private:
    std::string_view key_;
    std::size_t hash_;
public:
    KeyHashPair() = delete;
    KeyHashPair(std::string_view sv) : key_(sv), hash_(Hash{}(key_)) {}

    std::string_view key() const { return key_; }
    std::size_t hash() const { return hash_; }
};

struct Hash {
    using is_transparent = void;

    std::size_t operator()(std::string_view sv) const {
        return std::hash<std::string_view>{}(sv);
    }
    std::size_t operator()(KeyHashPair<Hash> pair) const {
        return pair.hash();
    }
};

struct KeyEqual {
    using is_transparent = void;

    bool operator()(std::string_view lhs, std::string_view rhs) const {
        return lhs == rhs;
    }
    template<typename Hash>
    bool operator()(KeyHashPair<Hash> lhs, std::string_view rhs) const {
        return lhs.key() == rhs;
    }
};

using Set = std::unordered_set<std::string, Hash, KeyEqual>;

int main() {
    Set set{"foo"};

    const std::string string{"foo"};
    const KeyHashPair<Set::hasher> pair{string};

    assert(set.contains(pair));
}

还是有点思路提升的,但并没有把hash存下来,其实更合理的思路是直接比较set内部的hash,可惜没有暴露

开源项目介绍

工作招聘

和群友聊天聊到了某些爱装逼的人,发现每一代学生都是这样的思维,沉迷某些技术 术语,爱装逼

虽然笔者讲出来有一点好为人师的感觉,但我还是很后悔大学浪费很多时间在嘴贫装逼上的。

那么问题来了,咱们读者是学生还是工作党,如果是学生,本周刊对你有没有收益?还是在咱这里学装逼来了,切记低调别装逼

如果不懂或者认为笔者有错误,大胆评论区指出,谢谢先,千万别模棱两可混过去了,笔者也不一定懂


上一期

看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持! 觉得写的不错那就给点吧, 在线乞讨 微信转账