2016-07-25 29 views
14

Während der Umsetzung std::any C++ 17 ist gemäß der Spezifikation verfügbar in this Wiki ich über etwas gestolpert, das mir unsinnig schien:Warum erlaubt C++ 17's std :: any keinen Rückgabewert von any_cast?

In the definition der freien Funktion std::any_cast, die Werte aus einer std::any Instanz abzurufen verwendet wird, eine Überlastung für r-Wert Referenzen geliefert wird (es ist die dritte):

template< class ValueType > 
ValueType any_cast(any&& operand); // (3) 

Jetzt gibt es eine Anforderung unterhalb der Synopse aufgelistet, die 2 und 3 zu Überlastungen gilt (dh einschließlich auch der r-Wert Überlast) :

2-3) Returns *any_cast<std::remove_reference_t<ValueType>>(&operand)

Die Definition scheint nicht wirklich zu erlauben, die Daten zu bewegen!

Der Funktionsaufruf wird nur auf die zeigerbasierte Überladung umgeleitet; die Information über die temporäre Natur von operandist verloren!

Ist es beabsichtigt, dass ich aus einer beliebigen Instanz nicht bewegen kann? Ist es nur ein Fehler im Wiki? Liege ich hier falsch?

+5

Verbunden: http://wg21.cmeerw.net/lwg/issue2509 –

+3

"Bereit - Die LWG hat Konsens erreicht, dass das Problem ein Fehler in der Norm ist, die vorgeschlagene Lösung korrekt ist und das Problem bereit ist Weiterleiten an den Gesamtausschuss für weitere Maßnahmen als Defect Report (DR). Normalerweise muss ein Problem eine vorgeschlagene Lösung in der Liste der derzeit veröffentlichten Probleme haben, deren Wortlaut sich während der LWG-Überprüfung nicht ändert, um in den Bereit-Status zu wechseln. " – Yakk

+2

SO scheint die' C++ 17' nicht zu akzeptieren Stichwort auf diesem, so zögern Sie nicht, meinen zweiten Versuch abzulehnen, sie zu addieren.Sie sind Synonyme, und "C++ 1z" ist als Master eingestellt. Das scheint falsch ... aber ich akzeptiere widerwillig @ Yakk Vorbehalt, Vergangenheit gegeben Beweise ;-) –

Antwort

10

Das Problem ist in WP Status zum Zeitpunkt der Abfassung dieses, which means:

WP - (Working Paper) - Der Beschlussvorschlag wurde als Technische Korrektur, aber die volle WG21 nicht akzeptiert /PL22.16 Der Ausschuss hat beschlossen, die vorgeschlagene Entschließung des Defect Reports auf das Arbeitspapier anzuwenden.

Siehe LWG hier für weitere Informationen: http://wg21.cmeerw.net/lwg/issue2509

Eine vorgeschlagene Lösung ist in der Tat

Für die dritte Form, wenn is_move_constructible_v<ValueType> wahr ist und is_lvalue_reference_v<ValueType> falsch ist, std::move(*any_cast<remove_reference_t<ValueType>>(&operand)), andernfalls *any_cast<remove_reference_t<ValueType>>(&operand)

Und die Fehlerbericht Liste Auflistung der WP: http://cplusplus.github.io/LWG/lwg-defects.html#2509

+2

Es ist tatsächlich in [WP] (http://cplusplus.github.io/LWG/lwg-defects.html#2509) . –

+1

@TC Danke. Aktualisierung. –

+2

@TC. T o diejenigen, die nicht jedes Akronym mit 2 Buchstaben verstehen, scheint [WP] (https://cplusplus.github.io/LWG/lwg-active.html#WP) der Zustand nach [DR] zu sein (https://cplusplus.github.io/LWG/lwg-active.html#DR) wo der Ausschuss die Änderung in das Arbeitspapier gefaltet hat (dh es ist in gewisser Hinsicht ein "akzeptierter" Fehlerbericht? Aber nicht so akzeptiert, dass es 100% sicher ist, in den nächsten Standard zu gehen, nur 99,9%?), Aber ich verstehe Meta-Standard nicht gut genug, um sicher zu sein, wenn ich diese Definitionen richtig lese. – Yakk

-1

Die Implementierung von std::any, die nicht kopiert werden muss, ist durchaus möglich. Es gibt nur ein Problem: Was machen Sie, wenn der Benutzer eine Kopie von std::any anfordert? Eine Lösung für dieses Problem ist, std::any move-only zu machen, die andere ist es, eine Exception auf den Kopierkonstruktor zu werfen, wenn der zugrunde liegende Typ move-only ist, und eine andere, dass der zugrunde liegende Typ kopiert werden kann. Die dritte Lösung wurde gewählt.

Die auf ValueType seine Kopie Anforderungen konstruierbar ist völlig in Ordnung - da ein Typ, der in der std::any Instanz kann nicht kopiert wird konstruierbar ist nicht möglicherweise gespeichert werden, std::any_cast und kann eine immer versagende warf einen Compiler-Fehler machen.

Nun, die Tatsache, dass die Implementierung von ValueType any_cast(any&& operand) keine Verschiebung zulässt, scheint ein Versehen zu sein - schließlich ist eine Kopie eine vollkommen gute Implementierung des Verschiebens, und die Implementierung ist frei, den Job an den Move-Konstruktor zu delegieren wenn es da ist, und um Konstruktor zu kopieren, wenn nicht.

+5

Ich sehe nicht, wie das auf die spezifische Frage bezogen wird –