一、局部变量
思想:使用auto初始化变量,具体类型后置
#include <cstdint>
#include <cstring>
#include <iostream>
#include <type_traits>
using namespace std;
int main(int argc, char **argv) {
//不好的做法:
int i1;
//好的做法
//原始做法
int i = 0;
cerr << i << endl;
// 使用auto
auto j = 0;//auto j =int();
cerr << j << endl;
auto z = [&]() {
for (int i = 0; i < argc; ++i) {
if (!strcmp(argv[i], "-h"))
return i;
}
return -1;
}();
cerr << z << endl;
return 0;
}
#include <chrono>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>
#include <vector>
#include <chrono>
using namespace std;
struct C {
int a;
int b;
};
using namespace std::literals;
int main(int argc, char **argv) {
// 好的做法
auto s1 = std::string("hello");
// 好的做法
auto s2 = "hello"s;
1s;
return 0;
}
二、结构体变量初始化
#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>
using namespace std;
struct C {
int a;
int b;
};
int main(int argc, char **argv) {
auto c = C{
};
cerr << c.a << endl;
// 不好的做法:
auto p_c = new C;
// 好的做法:
// make_unique会调用默认构造函数
auto n_c = std::make_unique<C>();
return 0;
}
#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>
using namespace std;
struct C {
// 避免写多余的构造函数
int a = 1;
std::string b = "wangji"s;
};
int main(int argc, char **argv) {
// 好的做法
auto c = C{
1, "w"};
// 好的做法,为struct C中新增成员,不影响这里的初始化
auto b = C{
.a = 100};
cerr << c.a << endl;
return 0;
}
三、for循环中可能存在的隐式类型转换:
#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>
#include <vector>
using namespace std;
struct C {
int a;
int b;
};
int main(int argc, char **argv) {
auto a = std::vector<char>(0x1ffffff);
// 可能存在的隐式类型转换
size_t i = 0;
// 不存在隐式类型转换,auto i = (size_t)0;
auto i = size_t(0);
//不好的做法: i会被推到成int类型,
// a.size()是std::size_t类型,i < a.size()可能会造成代码死循环
for (auto i = 0; i < a.size(); ++i) {
cerr << a[i];
}
// 好的做法:
for (auto i = size_t(0); i < a.size(); ++i) {
cerr << a[i];
}
// 好的做法:static_cast<size_t>(0):防止C风格的强转:int*p;static_cast<size_t>(p)
// C风格强转:int*p;size_t(p) 或者reinterpret_cast<size_t>(p)
for (auto i = static_cast<size_t>(0); i < a.size(); ++i) {
cerr << a[i];
}
return 0;
}
四、函数
#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>
using namespace std;
// 不好的做法,防止函数修改参数,导致调用处的函数工作异常
float lerp(float from, float to, float fac) {
return fac * (to - from) + from; }
// 好的做法
struct Lerp {
float from;
float to;
float fac;
float operator()() const {
return fac * (to - from) + from; }
};
// 好的做法
struct LerpWithResult {
float from;
float to;
float fac;
struct Result {
float value;
float secondvalue;
};
Result operator()() const {
return {
.value = fac * (to - from) + from,
.secondvalue = fac * (from - to) + to};
}
};
int main(int argc, char **argv) {
auto x = lerp(1, 2, 0.2);
cout << x << endl;
// 好处:更好看,给那个参数赋值了
auto y = Lerp{
.from = 1, .to = 2, .fac = 0.2}();
cout << y << endl;
;
auto [u, v] = LerpWithResult{
.from = 1, .to = 2, .fac = 0.2}();
cout << u;
return 0;
}
参考: