你的書很舊,但基本上正確[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