2017-05-29 6 views
1

Ich habe ein seltsames Verhalten (in meinen Augen) von vector :: emplace_back() in gcc (Version 6.3.1) festgestellt. Implizit wird ein Typ auf einen anderen Typ konvertiert, obwohl der Konvertierungsoperator als explizit deklariert wurde.Implizite Konvertierung für expliziten Operator

class A 
{ 
public: 
    explicit A(double value) : 
     value{value} 
    {} 

    explicit operator double() const 
    { 
     return value; 
    } 

private: 
    double value; 
}; 

int main() 
{ 
    A a{0.0}; 
    std::vector<double> values; 
    values.emplace_back(a); // <- no error here!  

    return 0; 
} 

Ist es ein Fehler oder eine Funktion?

+0

'emplace_back' baut sich explizit aus dem angegebenen Parameter. – Jarod42

+0

Sie würden jedoch mit 'push_back' einen Fehler bekommen. – Jarod42

Antwort

1

Es ist im Grunde wie Jarod42 in den Kommentaren geschrieben, aber hier sind einige Details.

The emplace_back method emplaces ein Element, das

durch std :: allocator_traits konstruiert ::

konstruieren Wenn man sich construct anschaut, kann man es sehen placement new verwendet. Es ist im Wesentlichen etwas wie

new((void *)p) T(val) 

, die eine explizite ctor Anruf ist.

0

Von ISO [class.conv.fct]:

eine Konvertierungsfunktion (7.1.2) explizit sein kann, in welchem ​​Fall es nur als benutzerdefinierte Konvertierung für Direkt Initialisierung berücksichtigt ist (8.5). Andernfalls sind benutzerdefinierte Konvertierungen nicht darauf beschränkt, in Zuweisungen und Initialisierungen zu verwenden.

double b { A { .0 } }; // fine 
double d = A { .0 }; // wrong