C ++错误的构造函数被调用

时间:2015-08-27 15:38:11

标签: c++ c++11

我希望下面的代码能够打印Test::Test(string,string,bool),但是会打印Test::Test(string,bool)。为什么在提供两个字符串时只调用一个字符串参数的构造函数?当然一根弦不能转换成一个布尔......?我尝试添加显式关键字但它没有帮助。代码也在http://ideone.com/n3tep1

#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");
}

3 个答案:

答案 0 :(得分:6)

用于构造Test的参数类型为char const[4]

char const[4]衰减到char const*,必须转换为boolstd::string const&才能使函数调用明确无误。

可以使用标准转换规则将指针转换为bool

可以使用用户定义的转化规则将char const*转换为std::string const&

鉴于此,从char const*(指针)到bool的转换被认为是比从char const*std::string const&的转换更好的匹配。

因此,调用解析为第一个构造函数。

答案 1 :(得分:2)

"bar"属于char const [4]类型,从bool转换为std::string是标准转换序列,而转换为N T则是用户定义的转化。前者总是优先于后者。

来自N3337, [conv] / 1

  

标准转化是具有内置含义的隐式转化。第4条列举了全套此类转换。 标准转换序列是一系列标准转换,顺序如下:
   - 来自以下集合的零或一次转换:左值到右值转换,数组到指针转换,   和功能到指针的转换    - 来自以下集合的零或一次转换:整数促销,浮点促销,积分   转换,浮点转换,浮点积分转换,指针转换,指向成员转换的指​​针以及布尔转换
   - 零或一个资格转换。

在您的示例中,标准转换序列由数组到指针转换和布尔转换组成。

[conv.array] / 1

  

T数组”或“T未知范围数组”的左值或右值可以转换为“指向bool的指针”的prvalue。结果是指向数组的第一个元素的指针。

[conv.bool] / 1

  

算术,无范围枚举,指针或指向成员类型的指针的prvalue可以转换为false类型的prvalue。零值,空指针值或空成员指针值将转换为true;   任何其他值都将转换为Test("foo", "bar")。 ...

因此Test(const string&, bool)会导致调用using namespace std::literals::string_literals; Test("foo", "bar"s); // calls Test(const string&, const string&, bool) // ^ 构造函数而不是另一个构造函数。

触发对其他构造函数的调用的一种方法是使用string_literals

def s = '''Sample text 
--- Some text---- 
Another Sample text
-- Some more text ------
--Again some more text
More Sample text'''

println s.replaceAll(/(?m)^--.*$/, '')

答案 2 :(得分:0)

我希望编译器会抱怨模糊函数。

我期望的原因,以及你得到错误的构造函数的原因是,使用字符串文字导致指针,并且指针可以隐式地转换为布尔值。

在这种情况下,编译器显然认为布尔转换比转换为std::string更好。