2015-10-19 52 views
2

的可变数目我做了和锻炼上的参数变量数:函数重载和参数

import std.stdio; 

void main() { 

    enum Operation { add, subtract, multiply, divide } 

    struct Calculation { 
     Operation op; 
     double first; 
     double second; 
    } 

    double calculate1(in Calculation c) { 
     double result; 
     switch (c.op) { 
      case Operation.add : { 
       result = c.first+c.second; 
       break; 
      } 
      default : { 
       break; 
      } 
     } 
     return result; 
    } 

    double[] calculate(in Calculation[] ccs...){ 
     double[] result; 
     foreach(c;ccs){ 
      result ~= calculate1(c); 
     } 
     return result; 
    } 

    writeln(calculate1(Calculation(Operation.add, 1.1, 2.2))); 

    writeln(calculate 
      ([Calculation(Operation.add, 2.1, 2.2) 
      ,Calculation(Operation.add, 2.1, 2.2) 
      ,Calculation(Operation.add, 2.1, 2.2) 
      ,Calculation(Operation.add, 2.1, 2.2)] 
      ) 
      ); 
} 

它的工作原理确定:

3.3

[4.3, 4.3, 4.3, 4.3]

然后我试图尝试过载功能calculate并将calculate1名称更改为calculate。它带来了这个错误:

(27): Error: declaration calculate is already defined

(38): Error: function calculate (const(Calculation) c) is not callable using argument types (Calculation[])

我无法得到它。这种声明是否会带来模糊性,编译器会尝试将Calculation []作为计算参数?在这个程序中是否有可能超载calculate函数?

编辑:当从行double[] calculate(in Calculation[] ccs...){删除...歧义消失。现在将类型​​和Calculation作为参数,错误消息仍然相同。

EDIT2。 rcorre有趣的发现。将超载函数calculatemain更改为范围上限,此重载完全有效。

回答

1

(27): Error: declaration calculate is already defined

calculate函数被定义内部的main,但嵌套函数不能被重载。

编译器拒绝在main内创建calculate的第二个定义。

(38): Error: function calculate (const(Calculation) c) is not callable using argument types (Calculation[])

在这一点上,它只有1所定义calculate,这不能用​​调用。

尝试在main之外定义calculate或重命名其中一个功能。

如果你真的对超载设置,你可以使用一个typesafe variadic function

auto calculate(Args...)(in Args ccs){ 
    static if (Args.length == 1) { 
     // single arg, return a double 
     auto c = ccs[0]; 
     double result; 
     switch (c.op) { 
      case Operation.add : 
       result = c.first+c.second; 
       break; 

      default : 
       break; 

     } 
     return result; 
    } 
    else { 
     // multi arg, return a double[] 
     double[] result; 
     foreach(c;ccs){ 
      result ~= calculate(c); 
     } 
     return result; 
    } 
} 

以上无法通过一个​​,而是需要被称为calculate(calculation1, calculation2, ...),但你肯定能扩展它来处理获取数组。我们在这里需要一个模板,因为您正在重载返回类型(一次调用可能返回double,另一次返回double[])。

+0

编辑:我错了有关过载无效。这是一个(令人惊讶的是)有效的重载,只要它没有声明_inside_另一个函数(在这种情况下,'main') – rcorre

+0

确实。这是有效的超载。将删除我的答案。 – sigod

+0

交互查找。我会更新关于它的文本。 – Rijk