Jul*_*ian 24 c++ constructor casting type-conversion c++11
我读到,当提供适合转换构造函数或操作数时,C++编译器能够隐式转换类型.我实际上发现了看起来像这样的示例代码:
class Dog{
private:
string name;
public:
Dog(string n):name(n){} //This as the converting constructor
}
int main(){
Dog d = "rover";
}
Run Code Online (Sandbox Code Playgroud)
每当我运行此代码时,编译器都会抛出一条错误消息:
从'const char [6]'转换为非标量类型'Dog'请求Dog d ="rover";
在编译时我添加了编译器选项-std=c++11,所以它不应该是关于C++版本的,对吧?
我在网上找到的例子(至少对我来说)看起来完全相同,所以我不知道这里出了什么问题.
我对此主题的输入来自此视频:
转换构造函数和重载运算符 - 最新的
JDł*_*osz 36
您还需要了解您正在使用复制初始化而不是直接初始化.
它们是不同的,你需要了解它们是如何以及它们之间的关系explicit.您需要了解转换链的工作方式,最多涉及一个用户定义的转换.
Dog d1 ("rover");
Dog d2 = "rover";
Run Code Online (Sandbox Code Playgroud)
d2案例尝试将文字转换为狗,然后将其复制(移动)到d2.但是,这将是一个双转换:const char*对string,然后string到Dog.
d1案例构造d1将参数传递给构造函数,因此只有一个转换const char*为string.(在这两种情况下,推进const char [6]到const char*是有太多,但不向"只有一个"允许计数,在不同的类别之中.)
复制初始化不指定"rover"作为构造函数的参数.它说"这里有东西,但Dog这里需要一个".这是copy-init声明语法的右侧,而不是任何可识别的函数.编译器比必须找到合法的转换.
在直接初始化的情况下,你是简单地给一个函数(构造函数)的参数.编译器将您提供的内容转换为声明的参数类型.
son*_*yao 26
注意"rover"不是std::string,它const char[6](在末尾带有空字符)(可能会衰减const char*),要做Dog d = "rover";工作,"rover"需要转换std::string然后转换为Dog.
但是在一次隐式转换中,用户定义的转换不会被视为两次.
(强调我的)
在隐式转换的第二阶段调用用户定义的转换函数,该转换由零个或一个转换构造函数或零个或一个用户定义的转换函数组成.
您可以显式转换"rover"为使其工作.std::string
Dog d = std::string("rover");
Run Code Online (Sandbox Code Playgroud)
πάν*_*ῥεῖ 17
您需要另一个允许您从以下构造的构造函数const char*:
Dog(const char* n):name(n){}
Run Code Online (Sandbox Code Playgroud)
请记住,这"rover"不是a std::string,并且不会推断出类型隐式使用转换构造函数.正如@songyuanyao在回答中提到的,转换只会进行一次.
另一种选择是写:
Dog d = std::string("rover");
Run Code Online (Sandbox Code Playgroud)