C++:没有匹配的调用函数:为什么需要一个空的构造函数?
C++: no matching function for call: why is an empty constructor needed?
当我尝试编译以下代码时:
class a {
int i;
public :
a(int);
};
class b {
a mya;
int j;
public:
b(int);
};
a::a(int i2) {
i=i2;
}
b::b(int i2) {
mya=a(i2);
j=2*i2;
}
int main() {
}
我收到以下错误:
prog.cpp:21:12: error: no matching function for call to ‘a::a()
b::b(int i2) {
^
prog.cpp:17:1: note: candidate: ‘a::a(int)
a::a(int i2) {
^
prog.cpp:17:1: note: candidate expects 1 argument, 0 provided
prog.cpp:1:7: note: candidate: ‘constexpr a::a(const a&)’
class a {
^
prog.cpp:1:7: note: candidate expects 1 argument, 0 provided
prog.cpp:1:7: note: candidate: ‘constexpr a::a(a&&)
prog.cpp:1:7: note: candidate expects 1 argument, 0 provided
似乎期望 class a 没有参数的构造函数。我不明白为什么,我唯一一次创建类型为 a 的对象时,我调用了以 int 作为参数的构造函数。
我知道解决方案是为 a 添加一个不带参数的构造函数。
但是为什么?
感谢您的回答,
最好的问候,
杰罗姆
在b
的构造函数中,mya=a(i2);
是赋值(不是初始化)。在进入构造函数体之前,mya
被尝试默认初始化但是a
没有默认构造函数。
正如您所说,您可以为 a
添加默认构造函数,然后 mya
将被默认初始化,然后在 b
.
的构造函数中进行赋值
更好的方法是在member initializer list中初始化mya
。
b::b(int i2) : mya(i2) {
// ^^^^^^^^^
j=2*i2; // this could be moved to member initializer list too
}
(以下所有 ISO 标准参考均指 N4659: March 2017 post-Kona working draft/C++17 DIS)
根据 [class.base.init]/9,b
的 mya
成员是 a
类型,默认初始化,但 a
没有定义默认构造函数:
In a non-delegating constructor, if a given potentially constructed
subobject is not designated by a mem-initializer-id (including the
case where there is no mem-initializer-list because the constructor
has no ctor-initializer), then
- (9.1) if the entity is a non-static data member that has a default member initializer [...] the entity is initialized from its default member initializer as specified in [dcl.init];
- (9.2) otherwise, if the entity is an anonymous union or a variant member ([class.union.anon]), no initialization is performed;
- (9.3) otherwise, the entity is default-initialized.
此处,由于 mya
未与默认成员初始值设定项一起声明,因此适用 [class.base.init]/9.3。
[class.base.init]/9 的示例甚至涵盖了这种特殊情况:
[...] [ Example:
struct A {
A();
};
struct B {
B(int);
};
struct C {
C() { } // initializes members as follows:
A a; // OK: calls A::A()
const B b; // error: B has no default constructor
int i; // OK: i has indeterminate value
int j = 5; // OK: j has the value 5
};
— end example ]
您可以通过为 mya
提供默认成员初始值设定项来解决它,这样 [class.base.init]/9.1 就适用
class b {
a mya{42}; // default member initializer
int j;
public:
b(int);
};
或者,在b
的构造函数定义中使用成员初始化列表; b::b(int)
,这样 [class.base.init]/7 适用:
The expression-list or braced-init-list in a mem-initializer is used
to initialize the designated subobject (or, in the case of a
delegating constructor, the complete class object) according to the
initialization rules of [dcl.init] for direct-initialization.
[ Example:
struct B1 { B1(int); /* ... */ };
struct B2 { B2(int); /* ... */ };
struct D : B1, B2 {
D(int);
B1 b;
const int c;
};
D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ }
D d(10);
— end example ] [...]
因此直接初始化 mya
成员:
b::b(int i2) : mya(i2) {
// ^^^^^^^- member initializer list
j=2*i2;
}
当我尝试编译以下代码时:
class a {
int i;
public :
a(int);
};
class b {
a mya;
int j;
public:
b(int);
};
a::a(int i2) {
i=i2;
}
b::b(int i2) {
mya=a(i2);
j=2*i2;
}
int main() {
}
我收到以下错误:
prog.cpp:21:12: error: no matching function for call to ‘a::a()
b::b(int i2) {
^
prog.cpp:17:1: note: candidate: ‘a::a(int)
a::a(int i2) {
^
prog.cpp:17:1: note: candidate expects 1 argument, 0 provided
prog.cpp:1:7: note: candidate: ‘constexpr a::a(const a&)’
class a {
^
prog.cpp:1:7: note: candidate expects 1 argument, 0 provided
prog.cpp:1:7: note: candidate: ‘constexpr a::a(a&&)
prog.cpp:1:7: note: candidate expects 1 argument, 0 provided
似乎期望 class a 没有参数的构造函数。我不明白为什么,我唯一一次创建类型为 a 的对象时,我调用了以 int 作为参数的构造函数。
我知道解决方案是为 a 添加一个不带参数的构造函数。 但是为什么?
感谢您的回答, 最好的问候,
杰罗姆
在b
的构造函数中,mya=a(i2);
是赋值(不是初始化)。在进入构造函数体之前,mya
被尝试默认初始化但是a
没有默认构造函数。
正如您所说,您可以为 a
添加默认构造函数,然后 mya
将被默认初始化,然后在 b
.
更好的方法是在member initializer list中初始化mya
。
b::b(int i2) : mya(i2) {
// ^^^^^^^^^
j=2*i2; // this could be moved to member initializer list too
}
(以下所有 ISO 标准参考均指 N4659: March 2017 post-Kona working draft/C++17 DIS)
根据 [class.base.init]/9,b
的 mya
成员是 a
类型,默认初始化,但 a
没有定义默认构造函数:
In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then
- (9.1) if the entity is a non-static data member that has a default member initializer [...] the entity is initialized from its default member initializer as specified in [dcl.init];
- (9.2) otherwise, if the entity is an anonymous union or a variant member ([class.union.anon]), no initialization is performed;
- (9.3) otherwise, the entity is default-initialized.
此处,由于 mya
未与默认成员初始值设定项一起声明,因此适用 [class.base.init]/9.3。
[class.base.init]/9 的示例甚至涵盖了这种特殊情况:
[...] [ Example:
struct A { A(); }; struct B { B(int); }; struct C { C() { } // initializes members as follows: A a; // OK: calls A::A() const B b; // error: B has no default constructor int i; // OK: i has indeterminate value int j = 5; // OK: j has the value 5 };
— end example ]
您可以通过为 mya
提供默认成员初始值设定项来解决它,这样 [class.base.init]/9.1 就适用
class b {
a mya{42}; // default member initializer
int j;
public:
b(int);
};
或者,在b
的构造函数定义中使用成员初始化列表; b::b(int)
,这样 [class.base.init]/7 适用:
The expression-list or braced-init-list in a mem-initializer is used to initialize the designated subobject (or, in the case of a delegating constructor, the complete class object) according to the initialization rules of [dcl.init] for direct-initialization. [ Example:
struct B1 { B1(int); /* ... */ }; struct B2 { B2(int); /* ... */ }; struct D : B1, B2 { D(int); B1 b; const int c; }; D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ } D d(10);
— end example ] [...]
因此直接初始化 mya
成员:
b::b(int i2) : mya(i2) {
// ^^^^^^^- member initializer list
j=2*i2;
}