C ++ - Kompilierungsfehler beim Erstellen des Objekts mit rvalue std :: string

Ich bin mit einem Kompilierungsfehler konfrontiert, den ich nicht einmal beschreiben kann! Es verwirrt mich völlig.

Die Situatio:

Code versucht, ein Objekt auf dem Stapel mit einem rvalue std :: string zu erstellen, der mit einem char * initialisiert wird.

Der Cod:

#include <iostream>
#include <string>

class Foo
{
    public:
        Foo(double d)
            : mD(d)
        {
        }

        Foo(const std::string& str)
        {
            try
            {
                mD = std::stod(str);
            }
            catch (...)
            {
                throw;
            }
        }

        Foo(const Foo& other)
            : mD(other.mD)
        {
        }

        virtual ~Foo() {}

    protected:
        double mD;
};

class Bar
{
    public:
        Bar(const Foo& a, const Foo& b)
            : mA(a)
            , mB(b)
        {
        }

        virtual ~Bar() {}

    protected:
        Foo mA;
        Foo mB;
};

int main(int argc, char* argv[])
{
    if (argc < 3) { return 0; }

    Foo a(std::string(argv[1]));
    Foo b(std::string(argv[2]));

    Bar wtf(a, b);
}

Der Compilerfehler:

>g++ -std=c++11 wtf.cpp
wtf.cpp: In function ‘int main(int, char**)’:
wtf.cpp:58:17: error: no matching function for call to ‘Bar::Bar(Foo (&)(std::string*), Foo (&)(std::string*))’
     Bar wtf(a, b);
                 ^
wtf.cpp:38:9: note: candidate: Bar::Bar(const Foo&, const Foo&)
         Bar(const Foo& a, const Foo& b)
         ^
wtf.cpp:38:9: note:   no known conversion for argument 1 from ‘Foo(std::string*) {aka Foo(std::basic_string<char>*)}’ to ‘const Foo&’
wtf.cpp:35:7: note: candidate: Bar::Bar(const Bar&)
 class Bar
       ^
wtf.cpp:35:7: note:   candidate expects 1 argument, 2 provided
>

Sie werden nicht glauben, was die / eine Problemumgehung ist, entweder (oder zumindestI nicht). Wenn ich in meinem rvalue std :: string substr (0) aufrufe, ist der Compiler besänftigt. Aber ich verstehe nicht, warum dies einen Unterschied machen würde. Letztendlich..

std::string(argv[1]).substr(0)

... ist selbst noch ein rwert. Ich verstehe nicht, warum es aus der Sicht des Compilers anders ist.

D. Die folgende Änderung an main (...) ermöglicht den Erfolg der Kompilierung:

int main(int argc, char* argv[])
{
    if (argc < 3) { return 0; }

    Foo a(std::string(argv[1]).substr(0));
    Foo b(std::string(argv[2]).substr(0));

    Bar wtf(a, b);
}

Paar zusätzlicher Datenpunkte:

as Kompilieren ohne C ++ 11 macht keinen Unterschied (ich schließe es nur ein, um Zugriff auf std :: stod (...) zu erhalten, was neben dem Punkt steht g ++ (GCC) 5.4.0.Compilation-Umgebung ist cygwin. Ich habe versucht, den Konstruktor von Bar so zu ändern, dass er std :: string (anstelle von std :: string &) verwendet - dies hat keine Auswirkungen auf den Kompilierungsfehler.

Ich bin sterben um zu wissen, was dieses Problem ist. Das fühlt sich so außerhalb des linken Feldes an.

ielen Dank für jede Hilf

Antworten auf die Frage(6)

Ihre Antwort auf die Frage