C++14新特性
文章目录
- 1 关键字
- 1.1 auto 支持函数返回值类型推导
- 1.1.1 支持函数定义返回值类型推导
- 1.1.2 支持函数模板返回值类型推导
- 1.2 支持lambda表达式auto参数
- 1.3 constexpr的限制
- 1.4 `[[deprecated]]`标记
- 1.5 二进制字面量和字面量分隔符
- 1.6 `std::make_unique`
- 1.7 `std::intger_sequence`
- 1.8 `std::exchange`
- 1.9 `std::quoted`
- 2 模板
- 2.1 变量模板
- 2.2 别名模板
个人会用到的几个为:
- std::make_unique
- 二进制字面量
- [[deprecated]]标记
- std::exchange
- 别名模板
1 关键字
1.1 auto 支持函数返回值类型推导
1.1.1 支持函数定义返回值类型推导
auto func(int i); //前置声明
int main()
{
std::cout<<func(4)<<std::endl;
return 0;
}
auto func(int i) //C++11编译非法
{
return 1 + i;
}
[root@unbutu]$ g++ newCharacter.cpp -std=c++11
newCharacter.cpp:3:16: 错误:‘func’ function uses ‘auto’ type specifier without trailing return type
auto func(int i) //C++11编译非法
^
newCharacter.cpp:3:16: 附注:deduced return type only available with -std=c++14 or -std=gnu++14
1.1.2 支持函数模板返回值类型推导
template<typename T>
auto func(T data)
{
return data;
}
int main()
{
std::cout<<func(1)<<std::endl;
std::cout<<func(1.1)<<std::endl;
return 0;
}
1.2 支持lambda表达式auto参数
在C++11中,lambda
表达式参数需要使用具体的类型声明。
auto f = [](int a) {retun a;}
在C++14中, lambda表达式参数可以直接为auto
int main()
{
auto f = [] (auto a) { return a; };
std::cout << f(1) << std::endl;
std::cout << f(2.3) << std::endl;
return 0;
}
1.3 constexpr的限制
constexpr
是C++11
中引入的常量表达式和常量函数关键字,要求其值必须能在编译时确定。但是在C++11中减少了这些限制。
constexpr int factorial(int n) { // C++11中不可,C++14中可以
int ret = 0;
for (int i = 0; i < n; ++i) {
ret += i;
}
return ret;
}
c++11中constexpr函数中必须把所有东西放在一个单独的return语句中:
constexpr int func(bool flag) { // C++11
return 0;
}
constexpr int func(bool flag) { // C++11中不可,C++14中可以
if (flag) {
return 1;
}
else {
return 0;
}
}
1.4 [[deprecated]]
标记
用于指示某个函数、类、变量或特性已经过时或不推荐使用,可以在编译时获得告警信息。
1)标记函数
[[deprecated("This function is deprecated. Use newFunction() instead.")]]
void oldFunction();
(2)标记类
class [[deprecated("This class is deprecated. Use NewClass instead.")]] OldClass {
// 类定义
};
(3)标记变量
[[deprecated("This variable is deprecated. Use newVariable instead.")]]
int oldVariable;
1.5 二进制字面量和字面量分隔符
(1)二进制字面量和
支持使用0b开头的一串数字作为二进制表示的数
int a = 0b1011010001;
(2)字面量分隔符
支持使用单引号分割整形,例如通常三个数字一分割表示一个数量级的改变
int a = 123'456'789;
1.6 std::make_unique
C++11中有std::make_shared
,C++14中增加了std::make_unique
与直接使用new
操作符和手动构造std::unique_ptr
相比,std::make_unique
提供了更简洁的方式来动态分配资源,并且确保类构造和unique_prt指针构造一起进行,避免中间异常导致资源泄漏问题。
std::unique_ptr<int> ptr = std::make_unique<int>();
1.7 std::intger_sequence
表示一个编译时的整形虚列
1.8 std::exchange
这个函数接受两个参数:一个是要替换值的对象 obj
,另一个是新的值 new_value
。函数将 obj
的值替换为 new_value
,并返回 obj
的旧值,new_value的值是以右值引用传递,其不会被改变。函数原型如下:
template< class T, class U = T >
T exchange( T& obj, U&& new_value );
(1)std::exchange
和std::swap
的区别
std::swap
用于交换两个变量的值,且不返回原来的值。std::exchange
用于替换一个对象的值,并返回该对象的旧值,只改变被替换的值,用于替换的值是右值引用,不会被替换。- 两者都可以用于变量或对象
1.9 std::quoted
c++14
引入std::quoted
用于给字符串添加双引号。
string str = "hello world";
cout << str << endl;
cout << std::quoted(str) << endl;
/***输出***
hello world
"hello world"
**********/
2 模板
2.1 变量模板
c++14支持变量模板。
template<typename T>
T data = T(3.1415926);
int main()
{
std::cout << data<int> <<std::endl;
std::cout << data<double> <<std::endl;
return 0;
}
2.2 别名模板
c++14支持别名模板,主要作用是使用using
替换typedef
定义模板类型的别名,简化复杂的模板类型定义,如容器、指针等。其语法如下:
template<typename T, typename U>
struct ExistingType {
T t;
U u;
};
template<typename T, typename U>
using oldName = ExistingType<T, U>;
也可以固定一个参数类型
template<typename T>
using newName = ExistingType<T, int>;
int main()
{
newName<int> LI;
oldName<int, int> li;
return 0;
}
使用 typedef 重定义类型是很方便的,但它也有一些限制,比如:
- 无法重定义一个模板
typedef std::map<std::string, int> map_int_t;
// …
typedef std::map<std::string, std::string> map_str_t;
// …
我们需要的其实是一个固定以 std::string 为 key 的 map,它可以映射到 int 或另一个 std::string。然而这个简单的需求仅通过 typedef 却很难办到。