函数的返回类型自动引用是什么意思?我只是不理睬它。我从AliÇehreli的在线书籍中选取了一个例子,并尝试以各种方式对其进行了调整,并观察了GDC生成的汇编程序,我仍然没有更明智。 (我是一位非常有经验的asm和C程序员,但是D的新手。)你真的需要使用这个功能吗?
答案 0 :(得分:6)
auto
返回功能'主要用例位于模板中,函数体根据某些编译时参数进行更改。 auto ref
只是将其扩展为允许ref
返回。看哪:
auto ref foo(string magic)() {
static if(magic == "use ref") {
int* x = new int;
return *x;
} else {
return 0;
}
}
void main() {
foo!""();
foo!"use ref"();
}
每个唯一的编译时参数集将生成不同的函数。这些不同的功能有完全不同的代码。
这是一个空字符串的函数:
Disassembly of section .text._D3iii15__T3fooVAyaa0_Z3fooFNaNbNiNfZi:
00000000 <_D3iii15__T3fooVAyaa0_Z3fooFNaNbNiNfZi>:
0: 31 c0 xor eax,eax
2: c3 ret
3: 90 nop
4: 90 nop
5: 90 nop
6: 90 nop
7: 90 nop
正如您所看到的,这是最微不足道的 - return 0
。那里没有花哨的参考。这是use ref
:
Disassembly of section .text._D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNcNfZi:
00000000 <_D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNcNfZi>:
0: 55 push ebp
1: 8b ec mov ebp,esp
3: b8 00 00 00 00 mov eax,0x0
8: 50 push eax
9: e8 fc ff ff ff call a <_D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNcNfZi+0xa>
e: 83 c4 04 add esp,0x4
11: 5d pop ebp
12: c3 ret
13: 90 nop
14: 90 nop
15: 90 nop
16: 90 nop
17: 90 nop
(被破坏的名称中的字符串为ascii的十六进制字符串(好吧,它实际上是UTF-8,unicode也可以!)字节btw,即75736520726566部分 - 将0x75识别为&#39; u&# 39;和0x66作为&#39; f&#39;。被破坏的名字可能会变得非常长,但是一旦你了解它,这个模式很容易阅读。)
该代码调用new
,因此正文更复杂,但请注意eax仍然在那里保存返回值...指针。现在,让我们从ref
中取出auto ref
并重新编译同样的内容。
第一个功能当然是一样的。第二个改变了:
Disassembly of section .text._D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNfZi:
00000000 <_D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNfZi>:
0: 55 push ebp
1: 8b ec mov ebp,esp
3: b8 00 00 00 00 mov eax,0x0
8: 50 push eax
9: e8 fc ff ff ff call a<_D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNfZi+0xa>
e: 8b 00 mov eax,DWORD PTR [eax]
10: 83 c4 04 add esp,0x4
13: 5d pop ebp
14: c3 ret
15: 90 nop
16: 90 nop
17: 90 nop
看到mov eax,DWORD PTR [eax]
?它不再返回指针(当然,它是ref
在引擎盖下返回的指针),但现在它指向它 - 正常的,非参考值返回。
这就是auto
返回与auto ref
之间的区别。
为了完整起见,我们将其更改为ref int
,看看会发生什么:
$ dmd iii
iii.d(6): Error: constant 0 is not an lvalue
iii.d(11): Error: template instance iii.foo!"" error instantiating
现在仅return 0
是一个错误,因为它不是有效的ref
。
实际用例是模板可以基于各种参数做出更复杂的决定,决定在他们的身体中做什么,从而做出返回类型。它可能只返回传递给它的参数的任何类型,它可能会检查平台版本(那就是一些丑陋的代码lol),无论如何。 auto ref
允许您涵盖各种情况,而无需自己编写单独的函数签名(以及函数体)。
答案 1 :(得分:1)
auto
。例如,以下两个函数都是相同的:
uint returnAUint(){
uint r=256;
return r;
}
auto function2(){
uint r=256;
return r;
}
和ref
表示该函数将返回指针/引用。所以auto ref
是一个函数,它将返回一个指向编译器必须自己弄清楚的数据类型的指针。