Function 返回自动参考的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-ref是什么意思?我只是不喜欢。我从Ali Chehreli的在线书籍中选取了一个例子,并以各种方式对其进行了改编,并查看了从GDC生成的汇编程序,但我仍然不是真正的聪明人。(我是一名经验丰富的asm和C程序员,但不熟悉D。)您什么时候真正需要使用此功能?

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;
}