Skip to content

败犬日报 2024-11-08

1. C++ ranges 有没有什么入门学习资料

https://hackingcpp.com/cpp/std/range_algorithms.html

https://hackingcpp.com/news/2023-02-19.html

2. 性能比较 vec.emplace_back(x)vec[x]

cpp
std::vector<double> result;
result.reserve(in.size());
size_t size = in.size();

for (size_t i = 0; i < size; i++) {
    result.emplace_back(std::sqrt(in[i]));
}
cpp
std::vector<double> result(in.size());
size_t size = in.size();

for (size_t i = 0; i < size; i++) {
    result[i] = std::sqrt(in[i]);
}

emplace_back 会检查并扩容。这个扩容行为是个复杂操作,导致编译器优化(比如向量化)比较困难。另一个角度是编译器没那么聪明。

vec[x] 没有检查就容易优化。

最容易让编译器优化的写法可能是:resize 后拿到 vec.data() 指针,直接操作指针。这样操作就不经过 vector 的成员函数。(群友表示经常这么干)

https://johnnysswlab.com/what-is-faster-vec-emplace_backx-or-vecx/

3. 昨天 vector<bool> 问题,群友尝试了特化回来

cpp
template <>
struct std::vector<bool> {
};

这是能过编译的,看起来特化了两次 vector<bool>(标准一次,这段代码一次),但是标准库的特化有内存分配器的模板参数 _Alloc 所以并不是同一种特化。

但是!还是不要这么写,给标准库容器特化是未定义行为(给标准库加东西的行为基本上都是)。

4. 很坑的题,如何取得一个对象的地址

& 是错的,因为 & 可以重载。正确答案是 std::addressof

另外同样地,如何安全地迭代器转指针?

&* 是错的,答案是 std::to_address

看一乐。