if constexpr与二阶段编译检查分析

#include<iostream>
#include<type_traits>
using namespace std;

void print(){}
template<typename T, typename... Types>
void print(T firstArg, Types... args)
{
	std::cout << firstArg << endl; //print first argument
	print(args...); // call print() for remaining arguments
}

/*
printtest 这一方式是错误的, 因为通常函数模板中 if 语句的两个分支都会被实例化。
是否使用被实例化出来的代码是在运行期间( run - time) 决定的;
而是否实例化代码是在编译期间(compile - time) 决定的。 
因此如果在只有一个参数的时候调用 print()函数模板, 虽然 args...为空, if 语句中的 print(args...)也依然会被实例化, 但此时没有定义不接受参数的 print()函数,因此会报错。
 */

template<typename T, typename... Types>
void printtest(T const& firstArg, Types const& ... args)
{
	cout << firstArg << endl;
	if(sizeof...(args) > 0) {
		printtest(args...);//即便if运行期不满足条件进入此处,依然需要实例化次处代码
	}
}

/*
这里如果只给 print()传递一个参数, 那么 args...就是一个空的参数包, 此时 sizeof...(args)等于
0。 这样 if 语句里面的语句就会被丢弃掉, 也就是说这部分代码不会被实例化。 因此也就不再需要一个单独的函数来终结递归。
事实上上面所说的不会被实例化, 意思是对这部分代码只会进行第一阶段编译, 此时只会做语法检查以及和模板参数无关的名称检查(参见 1.1.3 节) 。
*/

template<typename T, typename... Types>
void print17(T const& firstArg, Types const& ... args)
{
	cout << firstArg << endl;
	if constexpr (sizeof...(args) > 0) {//code only available if sizeof…(args)>0 (sinceC++17)
		print17(args...); //若编译期if成功则进行二阶段编译检查即进入实例化阶段,否则此处代码只进行第一阶段编译检查,即不进行实例化阶段
	}
}

int main()
{
	print("hello", 45, 3.14, 'c', string("world"));
//!	printtest("hello", 45, 3.14, 'c', string("world"));
	print17("hello", 45, 3.14, 'c', string("world"));
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值