C++ C++;调用了错误的构造函数
我希望下面的代码打印C++ C++;调用了错误的构造函数,c++,c++11,C++,C++11,我希望下面的代码打印Test::Test(string,string,bool),但是它打印Test::Test(string,bool)。当提供两个字符串参数时,为什么它调用只接受一个字符串参数的构造函数?当然字符串不能转换为布尔。。。?我尝试添加显式关键字,但没有帮助。代码也位于 #包括 #包括 使用名称空间std; 课堂测试 { 公众: 测试(常量字符串和str1,bool标志=false) { cout我希望编译器会抱怨函数不明确 我期望的原因是,如果调用了错误的构造函数,那么使用字符串
Test::Test(string,string,bool)
,但是它打印Test::Test(string,bool)
。当提供两个字符串参数时,为什么它调用只接受一个字符串参数的构造函数?当然字符串不能转换为布尔。。。?我尝试添加显式关键字,但没有帮助。代码也位于
#包括
#包括
使用名称空间std;
课堂测试
{
公众:
测试(常量字符串和str1,bool标志=false)
{
cout我希望编译器会抱怨函数不明确
我期望的原因是,如果调用了错误的构造函数,那么使用字符串文字将导致指针,并且指针可以隐式转换为布尔值
在这种情况下,编译器显然认为布尔转换比转换为std::string
更好。用于构造测试的参数类型是字符常量[4]
char const[4]
衰减为char const*
,必须转换为bool
或std::string const&
,以使函数调用明确无误
可以使用标准转换规则将指针转换为bool
可以使用用户定义的转换规则将char const*
转换为std::string const&
鉴于此,从指针char const*
到bool
的转换被认为比从char const*
到std::string const&
的转换更匹配
因此,调用解析为第一个构造函数。“bar”
的类型为char const[4]
,从它到bool
的转换是一个标准的转换序列,而到std::string
的转换是用户定义的转换。前者总是优于后者
从N3337开始,[conv]/1
标准转换是具有内置含义的隐式转换。第4条列举了此类转换的完整集合。标准转换序列是按以下顺序进行的标准转换序列:
-以下集合的零或一个转换:左值到右值转换,数组到指针转换,
和函数到指针的转换。
-以下集合的零或一次转换:整数提升、浮点提升、整数
转换、浮点转换、浮点整数转换、指针转换、指针到成员转换和布尔转换
-零或一个资格转换
在您的示例中,标准转换序列由数组到指针转换和布尔转换组成
[conv.array]/1
“数组的nt
”或“数组的T
”类型的左值或右值可以转换为“指针指向T
”类型的PR值。结果是指向数组的第一个元素的指针
[conv.bool]/1
算术、非范围枚举、指针或指向成员类型的指针的PR值可转换为bool
类型的PR值。零值、空指针值或空成员指针值可转换为false
;
任何其他值都将转换为true
因此,Test(“foo”,“bar”)
导致调用Test(conststring&,bool)
构造函数,而不是调用另一个构造函数
触发对另一个构造函数的调用的一种方法是使用
“bar”
不是std::string
,它是const char*
,指针可以隐式转换为bool
,并且该转换必须优先于std::string(const char*)
构造函数。第一个版本更匹配,请尝试新的测试(“foo”,std::string(“bar”))在一个有关联的注释中,通常不希望在C++代码中使用<代码>新的<代码>。如果可能的话,栈变量是首选的。只是因为你说你离开了一段时间,所以我就要做一个提示。谢谢。我使用C++ 11和最近碰到的一些其他东西使我相信字符串文字被视为STD::string,但是IG。因为它们只是被隐式转换,没有类似于我在这里遇到的ptr->bool这样的竞争转换。我避免使用新的,但在处理代码时添加了它。我遇到了同样的问题,通过将bool
更改为int
/char
,解决了这个问题,因为我真的不喜欢使用o记得在调用中编写一个明确的字符串结构,如@Melkon建议的。我启用了以下g++选项,但没有警告:-pedantic-Wall-Wextra。布尔转换比转换到std::string
更匹配。
#include <iostream>
#include <string>
using namespace std;
class Test
{
public:
Test(const string& str1, bool flag=false)
{
cout << "Test::Test(string,bool)" << endl;
}
Test(const string& str1, const string& str2, bool flag=false)
{
cout << "Test::Test(string,string,bool)" << endl;
}
};
int main()
{
Test* test = new Test("foo", "bar");
}
using namespace std::literals::string_literals;
Test("foo", "bar"s); // calls Test(const string&, const string&, bool)
// ^