函数重载和可变参数个数

Function Overloading and Variable Number of Parameters

我已经制作并练习了可变数量的参数:

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[] 作为 Calculation 参数发送?在这个程序中是否可以重载 calculate 函数?

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

编辑2。 rcorre 的有趣发现。将重载函数 calculatemain 移动到上层范围,此重载完全有效。

(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的定义,不能用Calculation[]调用。

尝试在 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;
    }
}

上面不能传递 Calculation[],而是需要作为 calculate(calculation1, calculation2, ...) 调用,尽管您当然可以扩展它来处理获取数组。我们在这里需要一个模板,因为您要重载 return 类型(一个调用可能 return 一个 double,另一个 return 一个 double[])。