现代C++ 类型推导

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++类型推导的一些理解,欢迎大家评论。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值