Konvertierungs operator



  • hallo leute,

    habe mit dem konvertierungs-operator gerade ein problem:
    folgender code:

    class data_field
    {
       public:
          ...
    }; /* class data_field */
    
    class prototype_field : private data_field
    {
       public:
          using base_class = data_field;
          ...
          operator base_class&(void) noexcept { return *this; }
          operator const base_class&(void) const noexcept { return *this; }
    }; /* class prototype_field */
    
    ...
    
    using fields_type = std::vector<prototype_field>;
    using result_type = std::vector<data_field>;
    fields_type m_fields;
    result_type m_vec;
    for(const auto &elem : m_fields)
    {
        m_vec.push_back(elem); // ERROR C2243
    }
    

    verwende VC++2017 15.9.11
    genaue Fehlermeldung:

    error C2243: "Typumwandlung": Konvertierung von "const prototype_field *" zu "const data_field &" ist bereits vorhanden, aber es kann nicht darauf zugegriffen werden.
    

    was übersehe ich hier? sitz jetzt schon ueber eine stunde dabei und seh den wald vor lauter baeume nicht.

    Meep Meep



  • Eine Conversion von einer derived class in eine private base ist IMHO nicht erlaubt. Erb public und wirf die conversion fuctions weg?

    edit: class.conv.fct/1:

    A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.



  • hi sword,

    data_field hat keinen virtuelle destructor.
    weißt du zufaellig nen grund warum das als protected/private base nicht erlaubt ist?

    hab jetzt der prototype_field eine member-funktion "auto assign_to(data_field&) -> void" spendiert. das reicht mir so auch.

    Meep Meep



  • @Meep-Meep sagte in Konvertierungs operator:

    data_field hat keinen virtuelle destructor.

    Ich sehe nicht, was das mit Konvertierung zu tun hat.

    weißt du zufaellig nen grund warum das als protected/private base nicht erlaubt ist?

    Außer "weil es so geschrieben steht" kann ich dazu nur raten: Weil der c-tor der base in der derived inaccessible ist? Konvertierungsoperatoren spielen dabei ja sowieso nicht mit.

    hab jetzt der prototype_field eine member-funktion auto assign_to(data_field&) -> void spendiert. das reicht mir so auch.

    Naja, bei dem von Dir gezeigtem Code mit dem push_back() auf den vector hilfts nicht.



  • "prototype_field" ist eine erweiterung von "data_field". data_field hat keinen virtuelle destructor also erbe ich privat und mache die funktionen von data_field via using erreichbar. wenn ich std:::string, std::vector oder sonstiges erweitere mach ich das genau so.
    warum soll assign_to nicht helfen?
    der code sieht jetzt so aus:

    ...
    fields_type m_fields;
    result_type m_vec;
    data_field temp;
    for(const auto &elem : m_fields)
    {
        elem.assign_to(temp);
        m_vec.push_back(std::move(temp));
    }
    ...
    

    Meep Meep



  • @Meep-Meep sagte in Konvertierungs operator:

    "prototype_field" ist eine erweiterung von "data_field". data_field hat keinen virtuelle destructor also erbe ich privat und mache die funktionen von data_field via using erreichbar. wenn ich std:::string, std::vector oder sonstiges erweitere mach ich das genau so.

    Wenn keine dynamische Polymorphie im Spiel ist kann man das schon machen. Du musst halt nur sicherstellen, daß nie nicht delete für ein derived über einen base class pointer aufgerufen wird. Mir wäre Composition trotzdem lieber.

    @Meep-Meep sagte in Konvertierungs operator:

    der code sieht jetzt so aus:

    Das geht auch eloganter ohne ein assign_to():

    #include <vector>
    
    class prototype_field;
    
    class data_field
    {
    public:
    	data_field() = default;
    	data_field(prototype_field const &other) {};
    };
    
    class prototype_field : private data_field
    {
    };
    
    int main()
    {
    	std::vector<prototype_field> m_fields;
    	std::vector<data_field> m_vec;
    
    	for (const auto &elem : m_fields)
    	{
    		m_vec.push_back( data_field{ elem } );
    	}
    }
    

    //edit: Wenn Du data_field evtl. nicht verändern kannst oder darfst, dann wäre wirklich Composition angebracht.


Log in to reply