奇怪的构造函数行为
Strange constructor behavior
我正在使用 Visual Studio 2013,这就是我想要弄清楚的:
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
int x = 1;
bool y = true;
A(int _x, bool _y) : x(_x), y(_y)
{
cout << "Constructor #1" << endl;
}
A(std::initializer_list<int> init_list)
{
cout << "Constructor #2" << endl;
}
};
int main(int argc, char** argv)
{
A Aobj1(10, false);
A Aobj2(20, "false");
A Aobj3{30, false};
A Aobj4{40, "false"};
return 0;
}
输出为:
Constructor #1
Constructor #1
Constructor #2
Constructor #1
第一次调用构造函数 #1 没问题
现在 Aobj2(int, string)
调用构造函数 #1 的第二个构造很奇怪。编译器如何使用字符串参数调用 (int, bool)
构造函数? "false" bool
甚至没有转换为 int.
Aobj3
也行。尽管 initializer_list
是 int 类型,但编译器会调用它,因为大括号初始化并将 bool 转换为 int。
这个又让我费解了。我原以为这是一个错误,因为无法将字符串转换为 int(就像 bool 那样),并且还希望编译器调用 initializer_list
构造函数,因为它是花括号初始化。但是编译器选择了 (int, bool) 构造函数。
编译器的逻辑背景是什么?
"false"
是一个 const char[6]
,它衰减为 const char*
,指针可以隐式转换为 bool
。这就是编译器可以使用 int
和 bool
调用构造函数的原因,因为允许编译器执行 one 隐式转换以使函数参数匹配。
Now the second construction of Aobj2(int, string)
calling constructor #1 is strange. How is the compiler calling the (int, bool)
constructor with a string argument?
更准确地说,"false"
是 const char[6]
类型,可以 decay to const char*
, i.e. a pointer, and then could implicitly convert 到 bool
。
A prvalue of integral, floating-point, unscoped enumeration, pointer, and pointer-to-member types can be converted to a prvalue of type bool
.
The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become false
. All other values become true
.
对于第4种情况,参数std::initializer_list<int>
无法匹配参数40, "false"
,因为没有隐式转换将指针转换为int
。然后选择带int, bool
的构造函数,因为如上所述"false"
可以隐式转换为bool
。
我正在使用 Visual Studio 2013,这就是我想要弄清楚的:
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
int x = 1;
bool y = true;
A(int _x, bool _y) : x(_x), y(_y)
{
cout << "Constructor #1" << endl;
}
A(std::initializer_list<int> init_list)
{
cout << "Constructor #2" << endl;
}
};
int main(int argc, char** argv)
{
A Aobj1(10, false);
A Aobj2(20, "false");
A Aobj3{30, false};
A Aobj4{40, "false"};
return 0;
}
输出为:
Constructor #1 Constructor #1 Constructor #2 Constructor #1
第一次调用构造函数 #1 没问题
现在
Aobj2(int, string)
调用构造函数 #1 的第二个构造很奇怪。编译器如何使用字符串参数调用(int, bool)
构造函数? "false"bool
甚至没有转换为 int.Aobj3
也行。尽管initializer_list
是 int 类型,但编译器会调用它,因为大括号初始化并将 bool 转换为 int。这个又让我费解了。我原以为这是一个错误,因为无法将字符串转换为 int(就像 bool 那样),并且还希望编译器调用
initializer_list
构造函数,因为它是花括号初始化。但是编译器选择了 (int, bool) 构造函数。
编译器的逻辑背景是什么?
"false"
是一个 const char[6]
,它衰减为 const char*
,指针可以隐式转换为 bool
。这就是编译器可以使用 int
和 bool
调用构造函数的原因,因为允许编译器执行 one 隐式转换以使函数参数匹配。
Now the second construction of
Aobj2(int, string)
calling constructor #1 is strange. How is the compiler calling the(int, bool)
constructor with a string argument?
更准确地说,"false"
是 const char[6]
类型,可以 decay to const char*
, i.e. a pointer, and then could implicitly convert 到 bool
。
A prvalue of integral, floating-point, unscoped enumeration, pointer, and pointer-to-member types can be converted to a prvalue of type
bool
.The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become
false
. All other values becometrue
.
对于第4种情况,参数std::initializer_list<int>
无法匹配参数40, "false"
,因为没有隐式转换将指针转换为int
。然后选择带int, bool
的构造函数,因为如上所述"false"
可以隐式转换为bool
。