栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

模板于泛型编程之declval

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

模板于泛型编程之declval

std::declval是c++11标准中出现的一个函数模板,这个函数模板长得比较奇怪,因为它没有函数体(没有实现,只有声明,故意这样设计的),所以无法被调用,一般都是用于的decltype,sizeof等关键字配合使用进行类类型推导、占用内存空间计算等。它的源码如下:

template
add_ravalue_reference_t declval() noexcept;

add_ravalue_reference(注意末尾没有_t,add_ravalue_reference_t是该类型对应的别名模板)是c++标准库中提供的一个类模板,他的功能是传入一个类型,返回该类型的右值引用类型。如:
(1)传入int类型,返回的是int &&类型;
(2)传入int &类型,则返回的还是int &,此处运用了引用折叠规则。
(3)传入int &&类型,返回的还是int &&类型,这里也运用了引用折叠规则。
从源码中可以看出declval的功能就是返回某个类型T的右值引用,不管该类型是否有默认构造函数,还是该类型是否可以创建对象。这些动作都是在编译时完成的,所以也称std::declval为编译时工具。

class cTest
{
public:
	cTest(int a)
	{
		cout << "构造函数n";
	}
	double myfunc()
	{
		cout << "myfuncn";
		return 1.1;
	}
};

问题:如何得到myfunc()这个成员函数的返回类型double?传统的做法如下:

int main()
{	
	cTest myobj(1);
	cout << typeid(decltype(myobj.myfunc())).name() << endl;
	
	system("pause");
	return 0;
}

结果:

从结果可以看出,为了获取myfunc的返回类型,必须要创建一个类cTest的对象;那么,可以进行深入一点的思考,创建类myobj很麻烦,还要提供实参,如果不创建类的对象,还想得到myfunc()成员函数的返回类型,这个想法能实现吗?当然可以~

int main()
{	
	
	cout << typeid(decltype(declval().myfunc())).name() << endl;
	
	system("pause");
	return 0;
}

结果:


从结果来看,既没有创建类的对象,也没有调用myfunc成员函数,却实实在在地得到了myfunc的返回类型。
declval作用总结:
(1)从类型转换的角度来说,将任意一个类型转换成右值引用类型。
(2)从假想创建出某类型对象的角度来说,配合decltype,令decltype表达式中不必经过该类型(一般指一个类类型)的构造函数,就能使用该类的成员函数。
注意,std::declval不能被调用,也不能创建任何对象。但是std::declval能够在不创建对象的情况下,达到创建了一个该类型对象的效果。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1001186.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号