2015-10-19 103 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