败犬日报 2024-11-20
1. 关于 safe c++ 的小作文
https://izzys.casa/2024/11/on-safe-cxx/
2. 别名不会产生新的符号
看一下这个代码,报错是 error: pack expansion argument for non-pack parameter 'T0' of alias template 'template<class T0, class ... Ts> using Tint = int'
。
cpp
template <typename T0, typename... Ts>
using Tint = int;
template <typename... Ts>
using A = Tint<Ts...>;
由于 C++ 规定,别名(using)不能产生任何新的符号,所以在实例化之前就得全替换掉。但是包参数(typename... Ts
)展开到非包参数(int
)上就没法做这样的替换。
解决办法是套个 struct:
cpp
template <typename T0, typename... Ts>
struct Tint {
using type = int;
};
template <typename... Ts>
using A = Tint<Ts...>;
模板的 name mangling 一个误解是 mangling 的类型是在整个模板替换完之后,把最终的类型给 mangling 了。但是实际上不是的。
https://godbolt.org/z/f46zKo31b 这里是直接 mangling 这个完全限定的特化类型。
3. 一个类有全局变量实例,且这个类的构造函数里通过这个全局变量读数据
那么这个全局变量的值是未指定的,后续需要重新赋值。
https://eel.is/c++draft/class.cdtor#example-2
4. 编译期笛卡尔积
比如 std::tuple A {m, n}, std::tuple A {o, p, q}, std::tuple A {x, y, z}
然后生成 std::tuple<std::tuple<m, o, x>, ...>
这个类型。
这个还是比较麻烦的,群友提供了实现 https://godbolt.org/z/en34P95cq。
5. c++98 古法炼钢实现 lambda
就是用 struct 模拟 lambda 行为:
cpp
#include <iostream>
int main() {
struct lambda {
int& y;
lambda(int& y) : y(y) {}
int operator()(int x) { return x + y; }
};
int y = 10;
lambda f(y); // 模拟 [&](int x) { return x + y; }
auto g = f(5);
std::cout << g << std::endl;
return 0;
}
群友公司根据这个原理写了一个宏实现的闭包。