none
クラスの初期化について RRS feed

  • 質問

  • 下記のソースで、変数c,dの違いが理解できません。(VC++2019)

    変数Cは、なぜcomple errorなるのでしょうか?

    #include <iostream>
    
    class AClass
    {
    public:
        AClass(int n) {
            std::cout << n << std::endl;
        }
        AClass(std::string s) {
            std::cout << s << std::endl;
        }
    };
    
    int main()
    {
        AClass a = 100;
        AClass b{ 200 };
    
        AClass c = "aaaa"; // compile error
        AClass d{ "bbbb" };
        std::string s = "cccc";
        AClass e = s;
    }
    

    2020年9月9日 0:33

回答

  • 規格的には<q>[class.conv] 4 At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.</q>でしたね。
    AClass d{ "BBBB" } の変換は1回必要(std::string(const char*))なので通ります。
    AClass c = "aaaa";は、変換が2回必要(AClass(std::string)とstd::string(const char*)) なので駄目です。


    jzkey

    • 回答としてマーク Brillia 2020年9月10日 3:56
    2020年9月9日 22:58

すべての返信

  • #include <string> 行がが必要なのは置いとくと、一見したところ問題が見つかりませんでした。
    出力されたエラーを張り付けてみてはどうでしょう。

    2020年9月9日 2:02
  • 下記が、compile errorの内容です。

    "const char [5]" から "AClass" に変換するための適切なコンストラクターが存在しません

    '初期化中': 'const char [5]' から 'AClass' に変換できません。

    コンストラクターはソース型を持てません、またはコンストラクターのオーバーロードの解決があいまいです。

    2020年9月9日 2:09
  • CはAClassの変換コンストラクタの駆動ですが、規格によればこのときは、「Implicit type conversions」は考慮されない(ほかの初期化・呼び出しでは考慮されると書いてある)ので、std::string(const char *)が呼ばれないからエラーになるんでしょう。
    AClassにconst char型コンストラクタを足すか、c = "aaaa"sとかにすれば通ります。

    jzkey

    • 回答としてマーク Brillia 2020年9月9日 2:57
    • 回答としてマークされていない Brillia 2020年9月9日 8:16
    2020年9月9日 2:13
  • すいません。一度は回答としてマークしたのですが、

    AClass d{ "bbbb" };

    は、暗黙的キャストが行われるのはなぜでしょうか?

    2020年9月9日 8:16
  • 規格的には<q>[class.conv] 4 At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.</q>でしたね。
    AClass d{ "BBBB" } の変換は1回必要(std::string(const char*))なので通ります。
    AClass c = "aaaa";は、変換が2回必要(AClass(std::string)とstd::string(const char*)) なので駄目です。


    jzkey

    • 回答としてマーク Brillia 2020年9月10日 3:56
    2020年9月9日 22:58
  • class AClass {
    public:
        AClass(const std::string s) {}
    };
    
    void funcA(const AClass a) {
    }
    
    int main() {
        funcA("aaa");                    // error
        funcA(AClass("bbb"));        // ok
        funcA(std::string("ccc"));   // ok
    }

    AClass(std::string)への直接の変換ができないからコンパイルエラーとなっている認識でしょうか。

    AClass(const char*){}を追加したらコンパイルが通りました。

    2020年9月10日 1:42