返回值类型推导
先看一段代码:
1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> using namespace std ;auto func (int i) { return i; } int main () { cout << func(4 ) << endl ; return 0 ; }
使用C++11编译:
1 2 3 4 5 ~/test$ g++ test.cc -std =c++11 test.cc:5 :16 : error: ‘func’ function uses ‘auto ’ type specifier without trailing return type auto func(int i) { ^ test.cc:5 :16 : note: deduced return type only available with -std =c++14 or -std =gnu++14
返回值类型推导也可以用在模板中:
1 2 3 4 5 6 7 8 9 10 #include <iostream> using namespace std ;template <typename T> auto func (T t) { return t; }int main () { cout << func(4 ) << endl ; cout << func(3.4 ) << endl ; return 0 ; }
注意 :函数内如果有多个return语句,它们必须返回相同的类型,否则编译失败
1 2 3 4 5 auto func (bool flag) { if (flag) return 1 ; else return 2.3 ; }
如果return语句返回初始化列表,返回值类型推导也会失败
1 2 3 auto func () { return {1 , 2 , 3 }; }
如果函数是虚函数,不能使用返回值类型推导
1 2 3 4 struct A { virtual auto func () { return 1 ; } }
返回类型推导可以用在前向声明中,但是在使用它们之前,翻译单元中必须能够得到函数定义
1 2 3 4 5 6 auto f () ; auto f () { return 42 ; } int main () { cout << f() << endl ; }
返回类型推导可用在递归函数中,但递归调用必须以至少一个返回语句作为先导,以便编译器推导出返回型
1 2 3 4 5 6 auto sum (int i) { if (i == 1 ) return i; else return sum(i - 1 ) + i; }
在C++11中,lambda表达式参数需要使用具体的类型声明:
1 auto f = [] (int a) { return a; }
在C++14中,对此进行优化,lambda表达式参数可以直接是auto
:
1 2 3 auto f = [] (auto a) { return a; };cout << f(1 ) << endl ;cout << f(2.3f ) << endl ;
变量模板
1 2 3 4 5 6 7 8 template <class T >constexpr T pi = T (3.1415926535897932385L );int main () { cout << pi<int > << endl ; cout << pi<double > << endl ; return 0 ; }
别名模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 template <typename T, typename U>struct A { T t; U u; }; template <typename T>using B = A<T, int >;int main () { B<double > b; b.t = 10 ; b.u = 20 ; cout << b.t << endl ; cout << b.u << endl ; return 0 ; }
constexpr的限制
C11中constexpr函数可以使用递归,在C 14中可以使用局部变量和循环
1 2 3 constexpr int factorial (int n) { return n <= 1 ? 1 : (n * factorial(n - 1 )); }
在C++14中可以这样做:
1 2 3 4 5 6 7 constexpr int factorial (int n) { int ret = 0 ; for (int i = 0 ; i < n; ++i) { ret += i; } return ret; }
C++11中constexpr函数必须必须把所有东西都放在一个单独的return语句中,而constexpr则无此限制
1 2 3 constexpr int func (bool flag) { return 0 ; }
在C++14中可以这样:
1 2 3 4 constexpr int func (bool flag) { if (flag) return 1 ; else return 0 ; }
deprecated
C++14中增加了deprecated
标记,修饰类、变、函数等,当程序中使用到了被其修饰的代码时,编译时被产生警告,用户提示开发者该标记修饰的内容将来可能会被丢弃,尽量不要使用
1 2 3 4 5 6 struct [[deprecated ]] A { };int main () { A a; return 0 ; }
当编译时,会出现如下警告:
1 2 3 4 5 6 7 ~/test$ g++ test.cc -std=c++14 test.cc: In function ‘int main()’: test.cc:11:7: warning: ‘A’ is deprecated [-Wdeprecated-declarations] A a; ^ test.cc:6:23: note: declared here struct [[deprecated]] A {
二进制字面量
C++14引入了二进制字面量,也引入了分隔符,防止看起来眼花
1 2 int a = 0b0001'0011'1010 ;double b = 3.14'1234'1234'1234 ;
std::exchange
1 2 3 4 5 6 7 8 9 int main () { std ::vector <int > v; std ::exchange(v, {1 ,2 ,3 ,4 }); cout << v.size () << endl ; for (int a : v) { cout << a << " " ; } return 0 ; }
可以看看 exchange
的实现
1 2 3 4 5 6 template <class T , class U = T >constexpr T exchange (T & obj , U && new_value ) { T old_value = std ::move (obj); obj = std ::forward<U>(new_value); return old_value; }
new_value
的值给了obj
,而没有对new_value
赋值
std::quoted
C++14引入std::quoted
用于给字符串添加双引号
1 2 3 4 5 6 int main () { string str = "hello world" ; cout << str << endl ; cout << std ::quoted(str) << endl ; return 0 ; }
编译&输出:
1 2 3 4 ~/test$ g++ test.cc -std =c++14 ~/test$ ./a.out hello world "hello world"
参考链接
《C++ Primer Plus》