函数重载和可变参数个数
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 的有趣发现。将重载函数 calculate
从 main
移动到上层范围,此重载完全有效。
(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[]
)。
我已经制作并练习了可变数量的参数:
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 的有趣发现。将重载函数 calculate
从 main
移动到上层范围,此重载完全有效。
(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[]
)。