你的书很旧,但基本上正确[1]。请注意,"Jane Doe"
不是std::string
,它是const char[9]
(并可能衰减到const char*
)。因此,对于CStr name3 = "Jane Doe";
,需要两个用户定义的转换(即,const char*
→std::string
和std::string
→CStr
),这在一个implicit conversion中是不允许的。
这也表明,如果CStr
的构造以const char*
作为其参数,CStr name3 = "Jane Doe";
可以正常工作,因为只需要一个用户定义的转换。
你可以通过添加显式转换减少一个:
CStr name3 = std::string("Jane Doe");
,或者使用string literal(因为C++ 14)直接,这是std::string
类型:
CStr name3 = "Jane Doe"s;
为什么没有将CStr :: name初始化为字符串s =“Jane Doe”?像string nameTest{"Jane Doe"};
这样的字符串测试工作,所以我认为这也会起作用。
你提的问题不够清楚,反正std::string nameTest{"Jane Doe"};
作品,因为(取决于你的误解,)(1)只有一个隐式转换(const char*
- >std::string
这里需要;(2)string nameTest{"Jane Doe"};
是直接初始化。
As @LightnessRacesinOrbit评论,direct initialization(ieCStr name3("Jane Doe")
或CStr name3{"Jane Doe"}
(因为C++ 11))将正常工作,而CStr name3 = "Jane Doe";
copy initialization是,它们在某些点是不同的:
另外,在复制初始化的隐式转换必须 产生Ť直接从初始化器,而例如 直接初始化期望从 初始值设定项到T的构造函数的参数的隐式转换。
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
,这是一个const char*
,必须被转换到CStr
直接;因为需要两次用户定义的转换,所以代码被拒绝。对于直接初始化,可以将Jane Doe
(const char*
)转换为参数CStr
的构造函数(即std::string
),然后调用CStr::CStr(std::string)
构造对象。
[1] "Jane Doe"
是一个C语言风格string literal是常量,由C++ 11是非法的其分配给char*
,例如
char * pc = "Jane Doe"; // illegal
const char * pcc = "Jane Doe"; // fine
顺便说一句,自从99年以来C++发生了很大的变化。自那时起,两项新标准添加了一堆新功能,并删除了一些过时的标准。 –
实际上,我的书桌上仍有该书的副本。非常有用的书可以作为C标准库的快速参考。 – user4581301
顺便说一下,你可以使用带有'CStr(char *)'构造函数的字符串文字的时代已经过去了。字符串文字不能转换为'char *'类型,只能转换为'const char *'。 – AnT