あなたの本は古いですが、基本的には右[1]です。 "Jane Doe"
はstd::string
ではなく、const char[9]
です(また、const char*
に減衰する可能性があります)。したがって、CStr name3 = "Jane Doe";
の場合、2つのユーザー定義の変換が必要です(つまり、const char*
- >std::string
およびstd::string
- >CStr
)。これは1つでは許可されていません。implicit conversion
これは、CStr
の構成がパラメータとしてconst char*
を取ると、CStr name3 = "Jane Doe";
がうまくいくことを示しています。これは、1つのユーザー定義の変換が必要なためです。
明示的な変換を追加することによって、いずれかを減らすことができる:
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"};
のような文字列テストが機能したので、これもうまくいくと思いました。
あなたの質問は(1)一つだけ暗黙の変換(const char*
std::string nameTest{"Jane Doe"};
作品(、あなたの誤解によって異なります)、ので、とにかく、十分に明確ではありません - >std::string
が、ここで必要とされている;(2)string nameTest{"Jane Doe"};
は直接初期化です。
@LightnessRacesinOrbitがコメントした通り、direct initialization(すなわちCStr name3 = "Jane Doe";
がcopy initializationである(C++ 11以降)CStr name3("Jane Doe")
又はCStr name3{"Jane Doe"}
)は、正常に動作するであろう、彼らはいくつかの点で異なっている:また
、コピー初期における暗黙の変換が から直接Tを生成しなければなりません初期化子、例えば、 直接初期化では、 イニシャライザから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
これはコピーの初期化のために、手段、const char*
ある引数Jane Doe
は、直接CStr
に変換されなければなりません。 2つのユーザー定義の変換が必要なため、コードは拒否されます。直接初期化の場合はJane Doe
(const char*
)をCStr
のコンストラクタの引数、つまりstd::string
に変換してから、CStr::CStr(std::string)
を呼び出してオブジェクトを構築します。
[1] "Jane Doe"
は、例えば、C++ 11からはchar*
に代入することは違法だ、CONSTであるCスタイルstring literalあります
char * pc = "Jane Doe"; // illegal
const char * pcc = "Jane Doe"; // fine
Btw、C++は'99以降かなり変更されました。新しい機能のヒープを追加し、一度廃止された機能の一部を削除した2つの新しい標準がその後リリースされました。 –
実際に私の机の上にその本のコピーがあります。非常に便利な本は、C標準ライブラリのクイックリファレンスとしての時間です。 – user4581301
ところで、 'CStr(char *)'コンストラクタで文字列リテラルを使う時間はなくなりました。文字列リテラルはもはや 'char *'型に変換することはできず、 'const char *'のみに変換することができます。 – AnT