if/switch 变量声明强化
void defineVarInIfOrSwithc() {
// 在if,switch中直接定义变量
vector<int> vec{1, 2, 3, 4, 5};
if (auto iter = std::find(vec.cbegin(), vec.cend(), 4);iter != vec.cend()) {
cout << *iter << endl;
}
if (auto iter = std::find(vec.begin(), vec.end(), 4);iter != vec.end()) {
*iter *= 10;
}
}
结构化绑定
结构化绑定对写代码的便利性提升了很多
std::tuple<string, int, double> foo() {
return std::make_tuple("hello world", 2, 3.14);
}
void structuredBind() {
// 结构化绑定
vector<std::pair<string, int>> strIntVec{{"hello", 1},
{"world", 2},
{"hello", 3},
{"motherland", 4}};
for (auto &[str, i] : strIntVec) {
cout << str << ": " << i << endl;
}
auto[str, i, d] = foo();
cout << str << ", " << i << ", " << d << endl;
}
一致的初始化{}(C++11)
// 一致的初始化
class Foo {
public:
Foo() : a(0), b(0) {}
Foo(int i, int j) : a(i), b(j) {}
int a;
int b;
};
void initializerList() {
// {}一致的初始化,始自C++11
Foo foo1(1, 2); // old c++
Foo foo2{1, 2}; // 自定义类,
Foo foo3{}; // 正确,用{}构造一个Foo对象,使用无参构造函数
vector<int> vec{1, 2, 3, 4, 5}; // 容器
std::unordered_map<string, int> strIntMap{{"lilei", 97},
{"hanmeimei", 99}}; // 容器
int arr[]{1, 2, 3, 4, 5}; // 数组
std::tuple<int, string, double> tuple3{1, "hello world", 3.14}; // std::tuple
std::pair<int, string> p{1, "hello motherland"}; // std::pair
}
自动推导
// from C++11, 尾置返回类型
template<typename T, typename U>
auto add1(T t, U u) -> decltype(t + u) {
return t + u;
}
// from C++14, auto自动推导
template<typename T, typename U>
auto add2(T t, U u) {
return t + u;
}
void autoDeduc() {
auto res1 = add1(1, 3.0);
auto isDouble = std::is_same<decltype(res1), double>::value;
auto res2 = add2(4.0f, 7.8);
auto isFloat = std::is_same<decltype(res2), float>::value;
return;
}
if constexpr, 声明常量表达式的判断条件,提高效率
// if constexpr, 声明常量表达式的判断条件,提高效率
template<typename T>
auto print_type_info(const T &t) {
if constexpr (std::is_integral<T>::value) {
return t + 1;
} else {
return t + 3.14;
}
}
void ifConstexpr() {
cout << print_type_info(1) << endl;
cout << print_type_info(1.0) << endl;
return;
}
如上代码类似于如下代码
类型别名模板
// 类型别名模板
// 模板和类型的不同:模板是用来产生类型的,传统C++中,typedef 可以为类型定义一个别名,但是却没有办法为模板定义一个新的名称
// 因为模板不是类型
template<typename T, typename U>
class MagicType {
public:
T t;
U u;
};
// template<typename T>
// typedef MagicType<std::vector<T>, std::string> FakeDarkMagic; // 错误, typedef不能是一个模板
typedef MagicType<int, double> RightDarkMagic1; // 正确, 类型别名
template<typename T>
using RightDarkMagic2 = MagicType<std::vector<T>, std::string>; // 正确, 类型别名模板
void typeAliaTemplate() {
typedef int (*process)(void *); // 函数指针
using newProcess = int (*)(void *); // 用新标准的using更直观了,支持范围更广
RightDarkMagic2<int> magic;
return;
}
默认模板参数(好像没什么用???)
// 默认模板参数 ,from c++11
template<typename T = int, typename U = int>
auto add3(T t, U u) {
return t + u;
}
void defaultTemplateParam() {
cout << add3(1, 2) << endl;
}
练习:结构化绑定的应用
// 结构化绑定练习
template<typename Key, typename Value, typename F>
void update(std::map<Key, Value> &m, F foo) {
for (auto&&[key, value] : m) {
value = foo(key);
}
}
void struBind() {
std::map<std::string, long long int> m{
{"a", 1},
{"b", 2},
{"c", 3}
};
// 调用update更新value值
update(m, [](std::string key) -> long long int {
// return std::hash<std::string>{}(key); // 注意,right,{}构造了一个std::hash<string>对象
return std::hash<std::string>()(key);
});
// 输出结果
for (auto&&[key, value] : m)
std::cout << key << ":" << value << std::endl;
}
参考:《现代C++教程:高速上手C++11 14 17 20》