Dra*_*utX 2 c++ string initialization
在C++ in Plain English,Second Edition(1999)中,书中有一节说"="可用于在调用正确的构造函数时进行初始化.就像给定一个类CStr和一个构造函数一样CStr(char*),本书说:
类似地,最后的声明调用构造函数CStr(char*):
Run Code Online (Sandbox Code Playgroud)CStr name3 = "Jane Doe";
我想用std::string构造函数尝试相同的东西.我的测试代码的一部分是这样的:
using namespace std;
class CStr {
private:
string name;
public:
CStr(string s): name(s) {}
};
int main() {
CStr name3 = "Jane Doe";
}
Run Code Online (Sandbox Code Playgroud)
但是,当我编译时,我在name3初始化中遇到错误:
"从'const char [9]'转换为非标量类型'CStr'请求".
为什么没有将CStr :: name初始化为字符串s ="Jane Doe"工作?字符串测试就像string nameTest{"Jane Doe"};工作一样,所以我认为这也会起作用.也许这本书很旧(这是我现在唯一的一本书),但我认为这个错误更多的是我.
你的书很旧,但基本上是正确的[1].注意"Jane Doe"不是std::string,它是const char[9](并且可能衰变const char*).因此CStr name3 = "Jane Doe";,需要两个用户定义的转换(即const char*- > std::string和std::string- > CStr),这在一个隐式转换中是不允许的.
这也证明了如果CStr构造const char*作为其参数,CStr name3 = "Jane Doe";可以正常工作,因为它只需要一个用户定义的转换.
您可以通过添加显式转换来减少一个:
CStr name3 = std::string("Jane Doe");
Run Code Online (Sandbox Code Playgroud)
或直接使用字符串文字(自C++ 14),其类型为std::string:
CStr name3 = "Jane Doe"s;
Run Code Online (Sandbox Code Playgroud)
为什么没有将CStr :: name初始化为字符串s ="Jane Doe"工作?字符串测试就像
string nameTest{"Jane Doe"};工作一样,所以我认为这也会起作用.
你的问题不够明确,无论如何,std::string nameTest{"Jane Doe"};因为,(取决于你的误解),(1)只有一个隐式转换(const char*- > std::string这里需要;(2)string nameTest{"Jane Doe"};是直接初始化.
正如@LightnessRacesinOrbit评论的那样,直接初始化(即CStr name3("Jane Doe")或CStr name3{"Jane Doe"}(从C++ 11开始))可以正常工作,而CStr name3 = "Jane Doe";在复制初始化时,它们在某些方面是不同的:
此外,复制初始化中的隐式转换必须直接从初始化器生成T,而例如,直接初始化需要从初始化器到T的构造函数的参数的隐式转换.
Run Code Online (Sandbox Code Playgroud)struct S { S(std::string) {} }; // implicitly convertible from std::string S s("abc"); // OK: conversion from const char[4] to std::string S s = "abc"; // Error: no conversion from const char[4] to S S s = "abc"s; // OK: conversion from std::string to S
这意味着,对于复制初始化,参数Jane Doe(即a const char*)必须CStr直接转换为; 因为需要两个用户定义的转换,所以代码被拒绝.对于直接初始化,将convert Jane Doe(const char*)转换为CStr构造函数的参数,即std::string首先,然后CStr::CStr(std::string)将调用它来构造对象.
[1] "Jane Doe"是一个c风格的字符串文字,它是const,从C++ 11中分配它是非法的char*,例如
char * pc = "Jane Doe"; // illegal
const char * pcc = "Jane Doe"; // fine
Run Code Online (Sandbox Code Playgroud)