2014-09-25 7 views
10

Erlaubt std::reference_wrapper<T> zulassen, dass T unvollständig ist, in der gleichen Weise, wie eine T& behandelt werden kann, ohne T abgeschlossen zu sein?Kann ich ein std :: reference_wrapper <T> instanziieren, wobei T ein unvollständiger Typ ist?

GCC 4.9 übernimmt die folgenden:

#include <functional> 

struct woof; 

struct test 
{ 
    test(woof& w) : w(w) {} 
    std::reference_wrapper<woof> w; 
}; 

struct woof 
{ 
    int a; 
}; 

int main() 
{ 
    woof w; 
    test t = w; // (braced-init would be better, but VS2012!) 
} 

Aber MSVS 2012 lehnt es mit der folgenden Meldung:

Fehler 1 Fehler C2139: 'Wuff': eine undefinierte Klasse wird nicht als erlaubt Argument Merkmal intrinsischen Typ Compiler '__is_abstract' c: \ Programme (x86) \ Microsoft Visual Studio 11.0 \ vc \ include \ type_traits 755 1 test3

I vermute, dies ist, weil die op() den vollständigen Typ benötigt, aber der Standard nicht erscheint, um jeden Weg anzugeben.

Welche der folgenden Implementierungen entspricht den Standardmandaten?

+2

Ich habe keine Ahnung, aber meine Wette ist nicht auf MS –

+1

Beachten Sie, dass MSVC schlägt fehl, unabhängig davon, was der Standard sagt: [Dieses Programm] (http://coliru.stacked-crooked.com/a/5a8e28dc279da2e5) doesn ' t kompilieren auf MSVC11 +, dank des 'is_abstract' Tests. – Xeo

Antwort

14

N3936 § 17.6.4.8 Weitere Funktionen [res.on.functions]:

1 In bestimmten Fällen (Ersatzfunktionen, Handler-Funktionen, verwendeten Operationen auf Typen Standardbibliothek Vorlage Komponenten zu instanziiert), Die C++ - Standardbibliothek hängt von Komponenten ab, die von einem C++ - Programm bereitgestellt werden. Wenn diese Komponenten nicht ihren Anforderungen entsprechen, stellt der Standard keine Anforderungen an die Implementierung.

2 Insbesondere werden die Wirkungen in den folgenden Fällen nicht definiert:

  • ...
  • wenn ein unvollständiger Typ (3,9) als Template-Argument wird verwendet, wenn eine Vorlage Komponente instanziiert wird, es sei denn, speziell für diese Komponente erlaubt.

Ein schneller Scan durch 20.9.3 Vorlage Klasse reference_wrapper [refwrap] zeigt keine solche spezifische Ausnahme für reference_wrapper, so dass Ihr Programm nicht definiertes Verhalten hat. Beide Implementierungen sind konform.

+1

Verdammt, zu langsam. +1 BTW: Ich denke, das ist ein Fall, in dem ein unvollständiger Typ erlaubt sein sollte. – Deduplicator

+0

Es scheint, dass die einzigen Komponenten mit dieser speziellen Ausnahme die Smart-Pointer-Typen sind. Ich denke, es wäre sehr sinnvoll, es auch für 'reference_wrapper' zu haben, weil es nützlich und trivial sein kann (da es normalerweise nur ein Wrapper um einen Zeiger ist, wie Smart-Pointer). Die ganze unvollständige Frage ist ein sehr schwacher Punkt im C++ - Standard (sowohl für Bibliothekskomponenten als auch für Regeln über Vorlagen), sie benötigt bessere Spezifikationen, wie klarere Regeln und erforderliche Diagnose/Fehler anstelle von UB. –

+5

@Deduplicator Das Problem mit unvollständigen Typen ist, dass 'reference_wrapper' mit dem alten' unary_function'/'binary_function' Protokoll für Rückwärtskompatibilität übereinstimmen muss.Um dies zu tun, muss es verschiedene Typdefinitionen basierend auf dem Typ des Template-Parameters definieren, z. [refwrap]/3: "Die Template Instanziierung ... soll definieren ...' argument_type' als Synonym für 'T1' nur dann, wenn der Typ' T' eines der folgenden ist: ... eine Klassenart mit ein Membertyp 'argument_type'; der Typ' T1' ist 'T :: argument_type'.". – Casey

Verwandte Themen