当前位置:网站首页>declval(指导函数返回值范例)

declval(指导函数返回值范例)

2022-07-06 10:05:00 发如雪-ty

有如下大代码:

int myfunc(int a, int b)
{
    
	return a + b;
}

template<typename T_F,typename...U_Args>
decltype(declval<T_F>() (declval<U_Args>()...)) testImpl(T_F func, U_Args...args)
{
    

	return func(args...);
}

int main()
{
    	
	int nSum = testImpl(myfunc, 13, 15);
	cout << nSum << endl;
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述
我们都知道函数类型是由返回值类型和参数类型决定的,与函数名没有关系,所以这里的myfunc的函数类型为int(int,int),前面的代表的是返回值类型,括号中的是两个参数类型。

上述代码有一段推导函数模板返回值类型的代码比较有意思。从main函数中可以看到,testImpl并没有指定模板参数,所以模板参数是由编译器推断的。下面将推断类型做一个简单的解释。
(1)T_F被推断为int(*)(int,int)
(2)U_Args代表一包类型,传入的是5,8,所以会被推导为int,int.
(3)值得注意的是decltype(declval<T_F>() (declval<U_Args>()...)),这种写法,我第一次接触的时候有点不习惯,但只要搞清楚它的作用就行了:根据函数类型以及参数类型推导出函数的返回值类型。

其实,这里还有一种不使用std::declval也能实现同样功能的写法-返回类型后置。实现起来要比std::declval清爽很多。

template<typename T_F, typename...U_Args>
template<typename T_F, typename...U_Args>
auto testImpl_2(T_F func, U_Args...args)->decltype(func(args...))
{
    

	return func(args...);
}

int main()
{
    	
	int nSum = testImpl_2(myfunc, 13, 15);
	cout << nSum << endl;
	system("pause");
	return 0;
}

结果:28

可能有的同学,会去掉->decltype(func(args...)),因为这样也能得到正确的答案,但这不是一个好主意,testImpl_2的本意是希望返回的类型与第一个类型模板参数T_F所代表的类型(既myfunc()函数返回类型)完全一样,而这正是“->decltype(func(args…))”代码存在的意义。

原网站

版权声明
本文为[发如雪-ty]所创,转载请带上原文链接,感谢
https://blog.csdn.net/FairLikeSnow/article/details/125590375