这个C++问题似乎非常基础和普遍,但我仍然希望有人能给出答案。
1)一个具有可变长度参数的函数和一个重载函数有什么区别? 2)如果我们有一个具有可变长度参数的函数和另一个具有相似参数的同名函数,我们会有问题吗?
发布于 2009-10-14 15:05:18
2)你的意思是下面的吗?
int mul(int a, int b);
int mul(int n, ...);让我们假设第一个乘以2个整数。第二个函数将通过var-args传递的n整数相乘。使用f(1, 2)调用将不会有歧义,因为通过“省略号”传递的参数与可能的最高成本相关联。但是,将实参传递给相同类型的参数与尽可能低的开销相关。因此,这个调用肯定会被解析到第一个函数:)
请注意,重载解析只比较相同位置的实参与实参转换。如果某个参数对的任一函数都有胜利者,那么它将很难失败。例如
int mul(int a, int b);
int mul(double a, ...);想象一下,第一个函数将两个整数相乘,第二个函数将以0.0结尾的doubles列表相乘。调用时,此重载集是有缺陷的且将是不明确的
mul(3.14, 0.0); 这是因为第二个函数在第一个参数中获胜,但第一个函数在第二个参数中获胜。第二个函数的第二个参数的转换成本高于第一个函数的第一个参数的成本,这并不重要。一旦确定了这样的“交叉”赢家情况,对这两个候选人的呼吁就是模棱两可的。
发布于 2009-10-14 15:00:52
1)一个重载的函数需要很多不同的原型和实现。它也将是类型安全的。
2)是的,这会给你带来问题,因为编译器不知道它需要调用哪个函数。它可能会也可能不会对此发出警告。如果不是这样,你很可能最终很难找到bug。
发布于 2009-10-14 15:15:24
重载函数可以有完全不同的参数类型,包括none,根据参数类型选择正确的参数类型。
可变长度参数要求至少存在一个参数。您还需要一些机制来“预测”下一个参数的类型(因为您必须在va_arg()中声明它),并且它必须是基本类型(即整数、浮点或指针)。常见的技术有“格式字符串”(如在printf()、scanf()中)或“标记列表”(参数列表中的每个奇数元素都是一个枚举,告诉后面的偶数元素的类型,用一个零枚举来标记参数列表的末尾)。
一般来说,重载是C++的一种方式。如果您最终确实需要一些类似于C++中的可变长度参数列表的东西,例如,为了方便地链接各种数字和类型的参数,请考虑C++ streams是如何工作的(那些连接的"<<“和”>>“):
class MyClass {
public:
MyClass & operator<<( int i )
{
// do something with integer
return *this;
}
MyClass & operator<<( double d )
{
// do something with float
return *this;
}
};
int main()
{
MyClass foo;
foo << 42 << 3.14 << 0.1234 << 23;
return 0;
}https://stackoverflow.com/questions/1566862
复制相似问题