2014-08-27 6 views
13

Damit ein Typ mit den C++ 03-Standardbibliotheken "gut spielt", wurde es als eine schlechte Idee betrachtet, die operator&() zu überlasten, da die Adresse den Typ korrekt verwenden und überladen unerwartete Probleme verursachen musste; klassisches Beispiel ist hier ATL::CComBSTR.Führt std :: addressof den STL-Operator und die Anforderung aus?

  • Mit dem Aufkommen von std::addressof() in C++ 11 und auf, nicht negiert dies, dass alte Anforderung (en) an den Typen in der Standardbibliothek verwendet?
  • Ist die Anforderung explizit in (oder aus) dem Standard in C++ 11 angegeben, d. H. Ist die von der Spezifikation vorgeschriebene Standardbibliothek std::addressof()?
+2

Welche "Anforderung" in C++ 03? Sind Sie sicher, dass es eine * Anforderung * und keine * Empfehlung * war? – Rapptz

+3

Was ist falsch mit CComBSTR? –

+0

@Rapptz, stimmt, ich bin mir nicht sicher, dass es als Voraussetzung beauftragt wurde, aber wenn über 'Operator &' überlastet, der Typ und die STL nicht gut "Bett Kerl". – Niall

Antwort

8

Die value_type eines Containers hat nur ein paar Anforderungen. Sie hängen hauptsächlich vom Behälter ab, aber für den allgemeinen Fall sind die Anforderungen mindestens MoveConstructible und MoveAssignable.

an den Blick C++ 11 Standardtabellen für das, was diese Anforderungen bedeuten, Sie diese:

§ 17.6.3.1 Tabelle 20 (MoveConstructible):

+----------------------------------------------------------+ 
| Expression   |  Post Condition    | 
|----------------------------------------------------------+ 
| T u = rv;   | u is equivalent to the    | 
|     | value of rv before the construction | 
+----------------------------------------------------------+ 
| T u(rv);   | T(rv) is equivalent to the   | 
|     | value of rv before the construction | 
+----------------------------------------------------------+ 
| rv's state is unspecified.        | 
|               | 
+----------------------------------------------------------+ 

§ 17.6.3.1 Tabelle 22 (MoveAssignable).

+-----------+--------------+-------------+----------------------+ 
    | Expression| Return Type | Return value| Post Condition  | 
    |-----------|--------------|-------------|----------------------| 
    | t = rv; | T&   | t   | t is equivalent to | 
    |   |    |    | the value of rv  | 
    |   |    |    | before the assignment| 
    |   |    |    |      | 
    +---------------------------------------------------------------+ 
    | rv's state is unspecified          | 
    |                | 
    +---------------------------------------------------------------+ 

Es gibt mehr Anforderungen an einen Behälter gegeben, je nachdem, was es ist, wie DefaultConstructible. Keine der Anforderungen erfordert jedoch, dass die nicht überlastet wird. Sie befassen sich hauptsächlich mit der Konstruierbarkeit der value_type anstatt der vom Typ bereitgestellten Operatorüberladungen.

Die anderen Tabellen finden Sie in § 17.6.3.1. Die Container-Anforderungen werden an § angegeben über 23.

5

Die C++ 03 CopyConstructible Anforderungen ausdrücklich die Forderung enthalten, dass die Adressoperator die tatsächliche Adresse des Objekts zurück, wie erwähnt in den Kommentaren 20,1 § .3 (Tabelle 30), daher könnten Typen, die diesen Operator überladen, Probleme mit der Standardbibliothek haben.

+------------+-------------+--------------------------+ 
| expression | return type | requirement    | 
+------------+-------------+--------------------------+ 
| T(t)  |    | t is equivalent to T(t) | 
+------------+-------------+--------------------------+ 
| T(u)  |    | u is equivalent to T(u) | 
+------------+-------------+--------------------------+ 
| t.~T()  |    |       | 
+------------+-------------+--------------------------+ 
| &t   | T*   | denotes the address of t | 
+------------+-------------+--------------------------+ 
| &u   | const T* | denotes the address of u | 
+------------+-------------+--------------------------+ 

C++ 11 vereinfacht die Bewegung (und kopieren konstruierbar und zuweisbar Definitionen) auf eine weitere grundlegende Syntax;

T (rvalue); // move construct 
T u = rvalue; // move assign 
T (value); // copy construct 
T u = value; // copy assign 

Es macht keinen Hinweis auf die überladene Anschrift des Betreibers, sondern es auch wenig Erwähnung std::addressof ausdrücklich erforderlich ist (außerhalb von einigen .resize() Funktionen) machen. std::allocator erfordert jedoch ausdrücklich, dass die Adresse der Typen auch bei Überlastung operator&() korrekt ist.

Abschließend kann es wenig in der Spezifikation geben, die Verwendung von std::addressof() zu fordern, aber angesichts der vereinfachten Anforderungen und expliziten Objektadressenanforderungen; die Verwendung von (oder ähnlich) ist sehr nahe daran, beauftragt zu werden.

Mein Take-Away hier ist; Wenn Sie einen generischen Code schreiben und die Adresse eines Objekts benötigen, verwenden Sie und bleiben Sie auf der sicheren Seite.

+0

Hervorhebung der Unterschiede zwischen C++ 03 und C++ 11 hier. – Niall

Verwandte Themen