Function 返回自动参考的D函数
函数的返回类型auto-ref是什么意思?我只是不喜欢。我从Ali Chehreli的在线书籍中选取了一个例子,并以各种方式对其进行了改编,并查看了从GDC生成的汇编程序,但我仍然不是真正的聪明人。(我是一名经验丰富的asm和C程序员,但不熟悉D。)您什么时候真正需要使用此功能?Function 返回自动参考的D函数,function,reference,d,return-type,Function,Reference,D,Return Type,函数的返回类型auto-ref是什么意思?我只是不喜欢。我从Ali Chehreli的在线书籍中选取了一个例子,并以各种方式对其进行了改编,并查看了从GDC生成的汇编程序,但我仍然不是真正的聪明人。(我是一名经验丰富的asm和C程序员,但不熟悉D。)您什么时候真正需要使用此功能?auto返回函数的主要用例是在一个模板中,其中函数体根据一些编译时参数进行更改auto-ref只是将其扩展为允许ref返回。瞧: auto ref foo(string magic)() { static if(m
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
(受损名称中的字符串是ascii的十六进制字符串(实际上是UTF-8,unicode也可以!)字节,75736520726566部分-将0x75识别为“u”,将0x66识别为“f”。D受损名称可能会长得离谱,但一旦了解它,模式就非常简单了。)
该代码调用new
,因此主体更为复杂,但请注意,eax仍保留返回值。。。指针。现在,让我们从auto-ref
中取出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
现在只返回0是一个错误,因为它不是有效的ref
实际的用例是,模板可以根据各种参数做出更复杂的决定,决定在它们的主体中做什么,从而决定它们的返回类型。它可能只返回传递到其参数中的任何类型,它可能检查平台版本(尽管这是一些难看的代码lol),等等
auto ref
允许您覆盖类似的各种情况,而无需自己编写单独的函数签名(以及函数体)。auto
用于让编译器确定函数将返回哪种类型。例如,以下两个功能相同:
uint returnAUint(){
uint r=256;
return r;
}
auto function2(){
uint r=256;
return r;
}
而
ref
意味着函数将返回指针/引用。因此,auto-ref
适用于一个函数,该函数将返回指向编译器必须自行确定的数据类型的指针。这是一个多么好的答案。非常感谢你。这应该被更广泛地宣传。AutoReF,智能代码固定器,只是使它工作的特点。[话题] BTW这超出了最新的C++语言的能力吗?(我对C++一无所知,只不过是专业的ASM和C。)你知道,我已经用了很多C++了很长时间了,没有跟上一切…但是我认为C++是不成熟的,因为它没有任何类似于<>代码> StasyII:< < /C> >这样分割一个物体。(它确实有预处理器,但这不适用于这里,它发生在任何语义模板之前)。我想,不确定,但我认为C++解决方案是重载两个模板,并使用替代等,使其工作。因此,据我所知,C++可以为函数调用方得到结果,但是函数实现将比D中的函数实现得更丑。
$ dmd iii
iii.d(6): Error: constant 0 is not an lvalue
iii.d(11): Error: template instance iii.foo!"" error instantiating
uint returnAUint(){
uint r=256;
return r;
}
auto function2(){
uint r=256;
return r;
}