败犬日报 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
。
看一乐。