C/C++编程:decltype

1059 篇文章 274 订阅

一、decltype

作用:返回操作数指定表达式的类型。在这个过程中,编译器会分析表达式并得到它的类型,却不实际计算表达式的值

在存在初始化代码的情况下,可以使用auto来自动决定变量的类型。还存在一种情况,我们希望变量的类型通过初始化代码之外的表达式推断得到。

假设有下面结构体:

struct Point{
   int x;
   int y;
};

在其他地方,可能这样定义point类型的变量/变量:

Point point;
Point* p1 = nullptr;

在C++中提供了另一种方式来决定变量的类型:decltype修饰符。利用它可以通过表达式的类型来决定变量的类型

decltype(point)* p2 = nullptr;

这两种方式有什么不同呢?当point的类型发生变化时,p1的类型需要一起修改,p2的类型就不需要修改

这和sizeof()的参数提倡使用变量名而不是数据类型是一样的道理。

 

二、auto与decltype

(1)auto用来实现变量的拷贝,包括变量值和类型。decltype只是用来获取变量的类型,并没有用其值来初始化新变量。

#include <iostream>
#include <typeinfo>
using namespace std;
extern const int a = 3;
int  main()
{
    auto ai(1);
    auto ato(ai);
    decltype(ai) dec;
    cout << typeid(ato).name() << " " << ato << endl;
    cout << typeid(dec).name();
    cout << typeid(dec).name() << " " << dec << endl;   // 23764(随机值)
    cin.get();
}

总结:decltype根据一个变量获取数据类型,然后我们可以用数据类型来创建变量,数组,指针等。

#include <iostream>
#include <typeinfo>

using namespace std;
extern const int a = 3;
void main()
{
	auto ai(1);
	auto ato(ai);
	decltype(ai)  dec[10]{0};
	cout << typeid(dec).name()  << endl; //	int[10]	
	for (auto i:dec)
	{
		cout << typeid(i).name() << i << endl; //int0
	}
	cin.get();
}

总结:auto只能拷贝一个变量,decltype本质是为了拷贝类型。

(2)与const的关系

#include <iostream>
#include <typeinfo>

using namespace std;

int main()
{
    const int ci(11);
	auto ac(ci);     //ci是int。autu复制类型和值,但是会忽略顶层的cosnt
	decltype(ci) dc(13);  //dc是const int。decltype是获取ci的类型,然后创建一个变量,const会带上

	cin.get();
}

总结:auto会忽略顶层const,decltype不会。auto编译器推断出的类型值可能会跟不同,比如顶层const,但是decltype会保留

三、模板指针

#include <iostream>

using namespace std;
template <typename T>
void show(T *p)   //模板指针
{
	cout << *p << endl; //*根据指针地址取出指向的内存里的值,然后打印出来
}

int main()
{
	int a(10);
	show(&a);  //传递a的指针
	auto a1('c');
	show(&a1);  //c
	cin.get();
}

decltype是内存拷贝

#include <iostream>


using namespace std;
template <class T>
void show(T *p)   //模板指针
{
	decltype(*p) num(*p);  //在内存里面对数据进行部分
	cout << num <<endl;
	cout << *p << endl;
}

int main()
{
	int a(10);
	show(&a);

	cin.get();
}

四、decltype根据引用创建数组

using namespace std;

template <class T>
void show(T *p)   //模板指针
{
	int a = *p;
	decltype(a) num[5]{ *p, *p, *p, *p, *p };
	for (auto i : num)
	{
		cout << i << endl;
	}
}

int main()
{
	int a(10);
	show(&a);
	cin.get();
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
In file included from /home/yhdr/2-test-2023-06_v3/sent.h:24:0, from /home/yhdr/2-test-2023-06_v3/sent.cpp:1: /usr/include/c++/7/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> > >’: /usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(double*, double&, double&, double&, double&, double&); _Args = {double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>}]’ /home/yhdr/2-test-2023-06_v3/sent.cpp:18:153: required from here /usr/include/c++/7/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> > >::_M_invoke(std::thread::_Invoker<std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> > >::_Indices)’ operator()() ^~~~~~~~ /usr/include/c++/7/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> >] _M_invoke(_Index_tuple<_Ind...>)
06-07

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值