从 C++17 起,如何从地址获得一个指定类型的对象?用
✅
std::launder
✅ alignas(T) char c[sizeof T];
✅ T* p = new(&c) T { /*args*/ };
✅ p->do_something(); // certainly ok
❌ reinterpret_cast<T*>(&c)->do_something(); // ub 因为 cast 结果没有指向一个 T 类型的对象✅
std::launder(reinterpret_cast<T*>(&c))->do_something(); // ok已知 `struct Test { };` 没有其他相关定义,那么 `std::is_default_constructible_v<std::hash<Test>>` 的值是?
Anonymous Quiz
46%
true
23%
false
23%
<ill-formed>
8%
<undefined behavior>
0%
<implementation defined>
string a="foo";
string b="bar";
pair<string,string> c=make_pair<string,string>(a,b);
以上C++98编译通过,C++11会CE(
string b="bar";
pair<string,string> c=make_pair<string,string>(a,b);
以上C++98编译通过,C++11会CE(
#include <iostream> 以后不能直接使用 std::istream 和 std::ostream ,应当 #include <istream> 和 #include <ostream> (C++11 之前今日疑似发现 GCC 10 的几个 bug
1. if constexpr (requires { xxx; }) 如果 xxx 里面有局部作用域的 ...(parameter pack 展开),特定情况下编译器只会检查语法而不会检查语义,导致不该被编译的代码实际上被编译了
2. 特定情况下,无参数的 lambda 表达式在用<>显式指定模板参数的同时省略了参数列表(),会导致编译器认为语法错误,形如 []<int x>{return x;}
1. if constexpr (requires { xxx; }) 如果 xxx 里面有局部作用域的 ...(parameter pack 展开),特定情况下编译器只会检查语法而不会检查语义,导致不该被编译的代码实际上被编译了
2. 特定情况下,无参数的 lambda 表达式在用<>显式指定模板参数的同时省略了参数列表(),会导致编译器认为语法错误,形如 []<int x>{return x;}
如果要开一个变量,其类型是模板参数,那么
* 要么,正确处理模板参数带 const 或带引用的情况(尤其是参数带着 && 的时候,一不小心就 const 或者 & 或者 && 了)
* 要么,先 decay 再存,也就是从存 T 变成存 decay_t<T>(看具体功能)
* 实在不行,static_assert 掉不愿意处理的情况(
要是忘了处理引用的情况,当场可能没锅,后续维护忘了这事,CE 事小, 涉及到生命周期的 UB 事大啊(
* 要么,正确处理模板参数带 const 或带引用的情况(尤其是参数带着 && 的时候,一不小心就 const 或者 & 或者 && 了)
* 要么,先 decay 再存,也就是从存 T 变成存 decay_t<T>(看具体功能)
* 实在不行,static_assert 掉不愿意处理的情况(
要是忘了处理引用的情况,当场可能没锅,后续维护忘了这事,CE 事小, 涉及到生命周期的 UB 事大啊(
