3

假设我有以下课程:

class A
{
public:
    A() {
    }

    A(int a):_a(a){
    }

    int _a;
};

以及以下功能:

void someFunc (A a)
{
    cout << a._a;
}

所以程序中的以下行可以正常工作:

someFunc (5); // Calls A(int a) Constructor.

但以下没有:

someFunc(); //Compile error

可以预期,如果它可以在获取整数时构建 A,那么为什么不使用默认构造函数也构建一个,当不带参数调用时呢?

4

5 回答 5

6

因为someFunc()需要一个参数,而您没有提供一个不提供的重载。int存在从to的隐式转换A,但这并不意味着您可以忽略函数的签名并在不带参数的情况下调用它。如果您想在没有参数的情况下调用它,他们会为a.

void someFunc(A a = A()) { 
    /* stuff */
}
于 2012-09-13T21:08:55.857 回答
3

因为您没有使用可转换的参数调用该函数,所以您调用了不带参数的函数。这是一种不同的超载,你没有提供。

考虑以下选项:

  • 像这样调用函数:someFunc(A()).
  • 定义函数参数的默认值:void someFunc (A a = A()) { ... }
  • 提供无参数重载:void someFunc() { someFunc(A()); }
于 2012-09-13T21:09:45.807 回答
1

这是因为 的签名与 的签名someFunc()不匹配void someFunc (A a)

根据 C++ 标准,第 13.3.2.3 节:

  • 首先,要成为一个可行的函数,候选函数应该有足够的参数以在数量上与列表中的参数一致。
  • 仅当 (m+1)-st 参数具有默认参数时,具有多于 m 个参数的候选函数才是可行的

在这种情况下,这些都不适用,因此对于使用空参数列表的调用void someFunc (A a)来说不可行。

于 2012-09-13T21:10:09.787 回答
0

我在这里并没有真正提供答案,但它仍然是有用的信息......有时你真的不想让someFunc(5)工作,因为它可能会导致错误的操作,或者只是误导。在这种情况下,您可以将构造函数声明为explicit

class A
{
public:
    A() {}   // Are you sure you don't want to initialise _a here?

    explicit A(int a) :_a(a) {}

    int _a;
};

正如其他人已经说过的那样,您可以为 指定默认参数someFunc

void someFunc( A a = A() );

现在:

someFunc();     // Calls A() by default

someFunc(5);    // Not allowed because of implicit construction

someFunc(A(5)); // Caller must pass an instance of A
于 2012-09-13T21:59:27.263 回答
0

挑剔。从 2003 C++ 标准开始,

17.4.3.2.1 全局名称 - ... - 每个以下划线开头的名称都保留给实现,用作全局名称空间中的名称

我会告诉你,以 _ 开头的任何变量名都是不好的做法。特别是当您可以将该实践扩展到命名变量参数(int foo(int _a)),或者不加思索地使用驼峰式(int _MyVar)。我个人会做类似的事情

int a_;

你真的会遇到麻烦吗?可能不是。但最好不要以下划线开头。永远不要在名称中的任何地方使用两个下划线,或者以一个下划线后跟一个大写字母开头,当然,也是。

于 2012-09-13T21:27:03.453 回答