C++类型推导,通常使用的是auto、decltype关键字来进行类型推导的,从而简化代码,方便编程,但是在获取方便的同时,我们需要对这些关键字有一些深入的了解。
一、获取函数的签名
__FUNCSIG__是MSVC下获取函数签名的宏,__PRETTY_FUNCTION__是GCC下获取函数签名的宏。
#ifdef __FUNCSIG__ // MSVC
#define PrintSig std::cout << __FUNCSIG__ << std::endl;
#else // GCC
#define PrintSig std::cout << __PRETTY_FUNCTION__ << std::endl;
#endif
使用一个例子来测试获取函数的签名
template<typename T1,typename T2>
void Print(T1 a,T2 b)
{
PrintSig;
}
// main函数调用
Print(1.0, 2u);
// 结果
void __cdecl Print<double,unsigned int>(double,unsigned int)
二、类型推导 - auto、decltype
1、构建一个int类型,一个const int类型,一个int&类型,一个const int& 类型。
int i = 1; // 左值
const int c = 3; // 常量
int& r = i; // 引用
const int& rc = c; // 常引用
// 我们使用C++的代码测试上述类型
if (std::is_reference_v<const int&>)
std::cout << "const int& is reference,";
else
std::cout << "const int& is not reference,";
if (std::is_const_v<const int&>)
std::cout << "const\n";
else
std::cout << "not const\n";
// 结果
const int& is reference,not const
为什么会出现const int& is reference,not const这种结果呢?
我通过查找资料,明白了为什么会出现这种现象,原因如下:
引用的const 限定符仅仅意味着不能通过引用参数修改值,但是它仍然可以被其他方法修改。
例子如下:
int a = 1;
const int &b = a;
std::cout << b << std::endl; // Prints 1
a = 2;
std::cout << b << std::endl; // Prints 2
所以我们不能假设const引用的值实际上是常数。
2、我们使用auto来推导上述类型
auto a = i;
auto ac = c;
auto ra = r;
auto rca = rc;
// 构建判断类型是否属于const类型,先移除变量的引用
template<typename T>
constexpr bool IsConst = std::is_const_v<std::remove_reference_t<T>>;
decltype(i) k = 10; // decltype(i) 推导i的类型 相当于 int k = 10;
if (std::is_reference_v<decltype(rca)>)
std::cout << "rca is reference,";
else
std::cout << "rca is not reference,";
if (IsConst<decltype(rca)>)
std::cout << "const\n";
else
std::cout << "not const\n";
// 结果
rca is not reference,not const
decltype(i) k = 10; decltype(i) 推导i的类型,从上面的代码所知,i的类型为int,所以decltype(i)推导出i的类型为int,即上述代码为 int k = 10;
3、我们使用decltype(auto)来推导上述类型
decltype(auto) da = i;
decltype(auto) dac = c;
decltype(auto) dra = r;
decltype(auto) drca = rc;
if (std::is_reference_v<decltype(drca)>)
std::cout << "rca is reference,";
else
std::cout << "rca is not reference,";
if (IsConst_1<decltype(drca)>)
std::cout << "const\n";
else
std::cout << "not const\n";
// 结果
rca is reference,const
为什么使用auto推断类型和使用decltype(auto)推断类型会有不同的结果,通过查阅资料发现auto与decltype(auto)是有一定的区别于联系的。
auto在表示类型时不会附带等号右侧类型的 ‘ & ’、‘ * ’ 以及顶层const,而decltype会附带表达式的 ‘ & ’、‘ * ’ 以及顶层const;
auto在遇到数组时,编译器会将其替换为一个指向数组首元素的指针,但是decltype不会;
以上是我对C++类型推导的一些理解,欢迎大家评论。