函数重载和可变参数个数

时间:2015-10-19 09:51:49

标签: d

我已经对可变数量的参数进行了练习和练习:

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):错误:声明计算已定义

     

(38):错误:函数calculate(const(Calculation)c)不能使用参数类型调用(Calculation [])

我无法得到它。这种声明是否带来歧义,编译器尝试将Calculation []作为Calculation参数发送?是否可以在此程序中重载calculate函数?

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

EDIT2。 rcorre有趣的发现。将重载函数calculatemain移动到较高范围,这种重载完全有效。

1 个答案:

答案 0 :(得分:1)

  

(27):错误:声明计算已定义

您的calculate函数已在main的中定义,但嵌套函数无法重载。

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

  

(38):错误:函数calculate(const(Calculation)c)不能使用参数类型调用(Calculation [])

此时,它只有calculate的1个定义,无法使用Calculation[]调用。

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

如果你真的开始重载,你可以使用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;
    }
}

上面的内容不能传递给Calculation[],而是需要调用calculate(calculation1, calculation2, ...),尽管你可以扩展它来处理数组。我们需要一个模板,因为你重载了返回类型(一个调用可以返回double,另一个调用返回double[])。