我想在编译时跟踪当前采用相同类型参数的一些函数的“类型”信息.这是一个例子;假设我有两个函数getThingIndex(uint64_t t)和getThingAtIndex(uint64_t tidx).第一个函数将参数视为事物的编码,对索引进行非平凡的计算,并返回它.然后,可以通过调用getThingAtIndex来获取实际的“东西”.另一方面,getThingAtIndex假设您正在查询结构并且已经有索引.两种方法中的后者更快,但更重要的是,我想避免将事物传递给getThingAtIndex或将索引传递给getThingIndex可能导致的麻烦.
我正在考虑为事物和事物索引创建类型,如下所示:
struct Thing { uint64_t thing; }
struct ThingIndex { uint64_t idx; }
然后改变上面函数的签名
getThingIndex(Thing t)
getThingAtIndex(ThingIndex idx)
现在,尽管Thing和ThingIndex编码相同
基础类型,它们在编译时和我是截然不同的
通过传递索引来减少制造愚蠢错误的机会
getThingIndex或getThingAtIndex的东西.
但是,我担心这种方法的开销.功能
被称为很多次(10s-100s,数百万次),我很好奇
编译器将基本上优化这些结构的创建
什么也不做,只编码编译时类型信息.如果编译器不会
执行这样的优化,有没有办法创建这些类型的“丰富类型”
零开销?
解决方法:
看一下拆卸.
unsigned long long * x = new unsigned long long;
0110784E push 8
01107850 call operator new (01102E51h)
01107855 add esp,4
01107858 mov dword ptr [ebp-0D4h],eax
0110785E mov eax,dword ptr [ebp-0D4h]
01107864 mov dword ptr [x],eax
*x = 5;
01107867 mov eax,dword ptr [x]
0110786A mov dword ptr [eax],5
01107870 mov dword ptr [eax+4],0
和结构.
struct Thing { unsigned long long a; };
Thing * thing = new Thing;
0133784E push 8
01337850 call operator new (01332E51h)
01337855 add esp,4
01337858 mov dword ptr [ebp-0D4h],eax
0133785E mov eax,dword ptr [ebp-0D4h]
01337864 mov dword ptr [thing],eax
thing->a = 5;
01337867 mov eax,dword ptr [thing]
0133786A mov dword ptr [eax],5
01337870 mov dword ptr [eax+4],0
两条指令没有区别.编译器并不关心this-> a是结构的成员,它访问它就像你刚刚声明unsigned long long a一样.