Was ist const void?

87

Die Beschreibung von std::is_voidbesagt, dass:

Gibt den Wert der Elementkonstante an, der gleich true ist, wenn T vom Typ void, const void, volatile void oder const volatile void ist.

Was könnte dann sein const voidoder ein volatile void?

Diese Antwort besagt, dass der const voidRückgabetyp ungültig wäre (kompiliert jedoch unter VC ++ 2015).

const void foo() { }

Wenn standardmäßig const voidungültig ist (VC ist falsch) - was ist es dann const void?

Ajay
quelle
15
Die Antwort, auf die Sie verlinken, besagt nicht, dass sie ungültig wäre, sondern dass sie "bedeutungslos" wäre, was ich als "keine Vorteile gegenüber voidohne const" bezeichnen würde.
@hvd, die Antwort besagt, dass der Compiler vor einer solchen Qualifikation warnen / Fehler machen sollte. Ich gehe davon aus, dass der C ++ - Standard keine Qualifikationen mitvoid
Ajay
2
Die Antwort besagt, dass der Compiler vor einer solchen Qualifikation warnen sollte, er erwähnt keinen Fehler und ein Fehler wäre falsch. Bei dieser Bemerkung geht es nur um die Qualität der Implementierung, nicht um die Konformität, aber ich kann verstehen, dass dies aus der Bemerkung selbst überhaupt nicht klar hervorgeht.
@Ajay Der Standard gibt nicht an, dass eine Warnung angezeigt werden soll, wenn Sie bedeutungslosen Code verwenden. Es war eine Entscheidung von gcc, Ihnen einen zusätzlichen Hinweis zu geben, dass dieser Code nichts tut. Aber VC ist in keiner Weise falsch.
user1942027
3
@ Ajay Die Antwort besagt, dass Clang eine Warnung gibt und dass nach Meinung des Autors andere Compiler dies tun sollten. Wenn der Standard dies nicht zulässt, ist dies ein Fehler und keine Warnung.
Molbdnilo

Antworten:

92

const voidist ein Typ, auf den Sie einen Zeiger bilden können. Es ähnelt einem normalen Void-Zeiger, aber die Konvertierungen funktionieren anders. Zum Beispiel const int*kann a nicht implizit in a konvertiert werden void*, aber es kann implizit in a konvertiert werden const void*. Ebenso, wenn Sie ein haben const void*, können Sie es nicht static_castzu einem int*, aber Sie können static_castes zu einem const int*.

const int i = 10;
void* vp = &i;                           // error
const void* cvp = &i;                    // ok
auto ip = static_cast<int*>(cvp);        // error
auto cip = static_cast<const int*>(cvp); // ok
Benjamin Lindley
quelle
4
Ihre Antwort ist zwar gut, gibt aber nicht den Grund dafür an const void, aber es handelt sich um nichtige und nicht leere Zeiger [mit (Nicht-) Konstanz].
Ajay
26
@ Ajay: Ich bin anderer Meinung. A const void*ist der einzige Grund, den Sie jemals sehen würden const void. Es kann als Vorlagenargument weitergegeben werden, aber dieser Argumenttyp wird immer nur mit einem *am Ende instanziiert .
Benjamin Lindley
@BenjaminLindley Sie können auch const voidin Frage vom Sprachanwalt gestellt sehen
cpplearner
3
@ Ajay: Irgendwann wird diese Frage zu einer philosophischen Frage. Der "Grund" dafür const voidist, dass alle Typen in C ++ erstellt werden können const. Es "existiert" auf die gleiche Weise wie es voidexistiert. Die Antwort von @Benjamin Lindley erklärt, was es ist, wenn Sie es sehen und wie Sie es verwenden.
Chris Beck
22

Wie void, const voidist ein Hohlraumtyp. Wenn const voides sich jedoch um einen Rückgabetyp handelt , constist dies bedeutungslos (wenn auch legal!), Da [Ausdruck] / 6 :

Wenn ein Wert anfänglich den Typ " cv T " hat, bei dem Tes sich um einen cv-nicht qualifizierten Typ ohne Klasse und ohne Array handelt, wird der Typ des Ausdrucks Tvor jeder weiteren Analyse angepasst .

Es ist jedoch selbst ein gültiger Typ und tritt beispielsweise in C-Standard-Bibliotheksfunktionen auf , wo es verwendet wird, um die Konstanzkorrektheit von Argumentzeigern sicherzustellen: int const*kann nicht konvertiert werden void*, aber void const*.

Columbo
quelle
const voidDa ein Rückgabetyp den Funktionstyp beeinflusst, ist er nicht völlig bedeutungslos.
cpplearner
1
@cpplearner Außer es ist in jeder praktischen Hinsicht, weil weder die Signatur der Funktion noch die Art eines Aufrufs davon betroffen sind.
Columbo
Nun, es kann die Signatur einer Funktionsvorlage ändern. +1 trotzdem
cpplearner
@cpplearner Fair genug - es ist jedoch immer noch eine Verschwendung von Tastenanschlägen.
Columbo
Wir sehen normalerweise: const int * kann nicht ungültig werden *, aber const void *.
mgouin
18

Typen können das Ergebnis von Vorlagen sein. Eine Vorlage const Tkann angeben und mit Tas instanziiert werden void.

Die verknüpfte Antwort ist irreführend bzw. eingeschränkt, da sie den Sonderfall eines Nicht-Vorlagentyps betrifft und selbst dann const voidmöglicherweise bedeutungslos ist , aber es handelt sich um gültigen Code .

DevSolar
quelle