说明
示例代码
std::any any = 0; // any = int(0)
std::cout << std::any_cast<int>(any) << std::endl; /// 0
std::cout << std::any_cast<double>(any) << std::endl; /// std::bad_any_cast异常
any = 1.0; /// 此时any又变为 double(1.0)
说明
示例代码
std::optional<int> make_int(int a, int b) {
return a < b ? std::optinal(a + b): std::optional<int>();
}
auto n = make_int(1, 2); /// n = 3
if (n) {
std::cout << n.value() << std::endl;
}
n = make_int(5, 1); /// n = null
std::cout << n.value_or(9) << std::endl; // 输出 9
说明
示例代码
std::variant<int, char, bool> var;
var = 12; // var 为int(12)
std::get<int>(var); // -> 12
std::get<0>(var); // -> 12
var.index(); // -> 0
var = 'A'; // var 为char('A')
std::get<char>(var); // -> 'A'
std::get<1>(var); // -> 'A'
var.index(); // -> 1
var = true; /// var为bool(true)
std::get<bool>(var); // -> true
std::get<2>(var); // -> true
var.index(); // -> 2
说明
示例代码
说明
示例代码
/// 定义一个字符串常量打印函数
void print(std::string_view msg) {
std::cout << msg << std:endl;
}
/// 使用
/// 1. 使用const char *做参数
print("Hello C string"); /// 虽然std::string做参数也能做到, 但是会执行字词内存拷贝用来构造一个std::string
/// 2. 使用std::string 做参数
std::string msg("Hello std::string");
print(msg); ///相当于 print(const std::string&)
说明
扩展的字面值, 使用原始字面值加特定后缀的方式可以直接创建某些特定的标准库类型
示例代码
using namespace std::literals;
// using namespace std::literals:string_literals
// using namespace std::literals:chrono_literals
auto str = "hello world"s; /// str 为std::string类型
auto seconds = 60s; /// seconds为std::chrono::seconds(60);
auto minutes = 10min; /// minutes 为 std::chrono::minutes(10);
auto hours = 2h; /// hours 为std::chrono::hour(2);
std::gcd
: 求两个整数的最大公约数std::lcm
: 求两个整数的最小公倍数auto gcd = std::gcd(6, 9); /// 3
auto lcm = std::lcm(6, 9); /// 18
说明
示例代码
int add(int a, int b) {
return a + b;
}
struct One {
void add(int a) {
std::cout << number + a << std::endl;
}
int number;
};
///调用普通函数
std::cout << std::invoke(add, 1, 2) << std::endl;
///lambda表达式
std::cout << std::invoke([](std::string name) {
return "hello" + name;
}, "oyoung") << std::endl;
///类成员函数
One one{1000};
std::cout << std::invoke(&One::number, one) << std::endl; /// 相当于 one.number
说明
示例代码
void show(std::string_view sv, char c) {
std::cout << sv << ": " << c << std::endl;
}
void say_self(std::string_view name, int age, bool gender) {
std::cout << "My name is " << name
<< ", I'm " << age << (age > 1 ? "years old": "year old")
<< ", and I'm a " << (gender ? "boy": "girl")
<< std::endl;
}
int main(int, char**) {
using namespace std::literals;
std::map<std::string, int> map {
{"A"s, 'A'},
{"B"s, 'B'}
};
for(auto pair: map) {
std::apply(show, pair); /// 等价于 show(pair.first, pair.second)
}
auto xiaoming = std::make_tuple("小明", 20, true);
auto xiaohong = std::make_tuple("小红", 16, false);
std::apply(say_self, xiaoming); /// 等价于 say_self("小明", 20, true)
std::apply(say_self, xiaohong); /// 等价于 say_self("小红", 16, false)
return 0;
}
说明
命名空间定义精简版
示例代码
/// C++17 之前需要这样写
namespace jdrv {
namespace ros {
namespace impl {
/// ...
}
}
}
/// C++17可以这样写
namespace jdrv::ros::impl {
}
说明
使用...
操作符来指代不定参数中的任意一个参数
示例代码
/// 判断所有参数是否都为真值
template<typename ...Args>
bool all(Args&& ...args) {
return (... and args);
}
auto is_all_true = all(1 == 1, 2 < 3, 4 > 5); /// = all(true, true, false) => ((true and true) and false)
/// 打印多个值
template<typename ...Args>
void print(Args&& ...args) {
(std::cout << ... << args) << std::endl;
}
print('A', 0, 1.5, true); /// 打印: A01.51
/// C++17之前
std::pair<int, bool> pair(0, true);
auto p = new std::array<int>{0, 1, 2, 3};
/// C++17
std::pair pair(0, true); /// 相当于 std::make_pair(0, true);
auto p = new std::array{0, 1, 2, 3}; /// 相当于 new std::array{0, 1, 2, 3};
说明
用来对std::pair, std::tuple, std::array对象进行解构
示例代码
/// std::pair
auto pair = std::pair(0, false);
auto [pf, ps] = pair; /// pf: 0, ps: false
/// std::tuple
auto tuple = std::make_tuple('A', true, 0, 1.0);
auto [t0, t1, t2, t3] = tuple; /// t0: 'A', t1: true, t2: 0, t3: 1.0
/// std::array
std::array<int, 2> array{100, 200};
auto [i0, i1] = array; // i0: 100, i1: 200