随着 C++ 的发展,C++ 引入了很多不同的关键字,下面简单介绍一些和 C 语言用法和功能有很多差异的关键字。先介绍一些简单的用法,以后再更加详细进行说明。
1. auto
- 常见的用法
* 推断函数的返回类型
* 结构化绑定
* 推断表达式类型
* 推断非类型模板参数的类型
* decltype(auto)
* 通用 lambada 表达式
重点介绍上述黑体的功能(注意使用 auto 声明多个变量的时候,必须是同一个类型)
推断函数返回值
#include <iostream>
#include <stdexcept>
#include <typeinfo>
#include <string>
const std::string strInfo = "Hello C++";
template<class T1, class T2>
auto getFoo(T1 data1, T2 data2) -> decltype(data1 + data2)
{
return (data1+data2);
}
const std::string& foo(void)
{
return strInfo;
}
int main(void)
{
auto a1 = 1.0f; //float
auto a2("Hello world"); //string (const char*)
auto a3 = new auto(9); //pointer int*
auto a4 = getFoo<double, double>(1000, 24.0); //return double
auto a5 = foo(); //string
const auto& a6 = foo(); //string&
std::cout<<"a1: "<<a1<<" datatype: "<<typeid(a1).name()<<std::endl;
std::cout<<"a2: "<<a2<<" datatype: "<<typeid(a2).name()<<std::endl;
std::cout<<"a3: "<<*a3<<" datatype: "<<typeid(a3).name()<<std::endl;
std::cout<<"a4: "<<a4<<" datatype: "<<typeid(a4).name()<<std::endl;
std::cout<<"a5: "<<a5<<" datatype: "<<typeid(a5).name()<<std::endl;
std::cout<<"a6: "<<a6<<" datatype: "<<typeid(a6).name()<<std::endl;
return 0;
}
a1: 1 datatype: f
a2: Hello world datatype: PKc
a3: 9 datatype: Pi
a4: 1024 datatype: d
a5: Hello C++ datatype: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
a6: Hello C++ datatype: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
auto 在单独推断变量的时候,似乎没有太大的优势,但是对于模板函数,优势就明显了。如果返回值类型过于复杂,我们可以结合 decltype 进行推断。值得注意的是 auto 去除了引用和const 限定符,会创建副本如上例 a5 一样。为了节约内存,可以使用 auto& 或 const auto&
2. delctype
关键字 decltype 把表达式作为实参,计算处该表达的类型。
int x =1024;
decltype(x) y = 256;
上述示例中,编译器会根据 x 的类型推断出 y 的类型是 int. auto 与 decltype 的区别在于,decltype 没有去除引用和 const 限定符。因此对于上例中的变量 a5 作如下定义:
decltype(foo()) a5 = foo();
结果导致 a5 为 const string&, 不用生成副本。decltype 在模板编程的时候变得十分有用。