为什么c ++在尝试将其转换为另一种类型时不能识别字符串?

Mah*_*ver 4 c++ casting

我有一个相当简单的类,看起来像这样:

class Person {
    public:

        Person(string name): _name(name) {};

        void greet(const Person& person) const {
            cout << "Hello, " <<  person._name << "!" << endl;
        };

    private:
        string _name;
};
Run Code Online (Sandbox Code Playgroud)

请注意,该greet方法采用该Person类型的参数.当我传递一个Person对象时,它按预期工作.现在让我们string以这种方式将它作为参数传递给它:

Person maher("maher");
maher.greet("sam");
Run Code Online (Sandbox Code Playgroud)

当试图在QT中运行该代码时(在运行ubuntu的机器上),它会生成以下错误: no matching function for call to ‘Person::greet(const char [4])’

我能够通过以这种方式转换字符串来解决此错误: maher.greet(string("sam"));

我的问题如下:为什么c ++ '看不到'我将字符串传递给greet方法?它与greet方法接受Person对象的事实有什么关系吗?

Mat*_*lia 6

maher是一个const char[6],sam是一个const char[4],并且都是const char *隐含的衰变,但它们实际上都不是std::string.

在函数调用中,如果explicit目标类型的非构造函数接受传递给函数的实际值的类型,则C++标准允许执行隐式转换.

当你调用构造函数时会发生这种情况:你传递一个const char[6],它会自动衰减到一个const char *; 目标类型是std::string,它有一个接受a的构造函数const char *; 调用此类构造函数,Person构造函数正确接收其std::string参数.

在第二种情况下,没有发生这种情况:Person没有接受a const char *的构造函数,只有接受a的构造函数std::string.要达到所需的Person类型,编译器必须首先转换const char *std::string,然后调用Person构造函数.这种双重转换是不允许的,主要是因为重载分辨率会变得完全混乱(已经存在),并且存在许多模糊的情况.

如果你想允许greet用C风格的字符串调用,你应该:

  • 创建一个构造函数Person,接受一个C风格的字符串(const char *),这样它就可以直接从a构造const char *,而不经过禁止的额外转换

  • 创建另一个重载greet以接受一个std::string.

另一方面,国际海事组织更清洁的替代方案就是保持现状; 调用者只需写

maher.greet(std::string("sam"));
Run Code Online (Sandbox Code Playgroud)