14 Stimmen

Was ist decltype(0 + 0)?

(Angeregt durch eine Antwort .)

Gegeben N3290, §7.1.6.2p4, wo die Listenpunkte nicht nummeriert sind, aber hier der Einfachheit halber nummeriert sind:

Der durch decltype(e) bezeichnete Typ ist wie folgt definiert:

  1. Wenn e ein nicht parenthesierter id-Ausdruck oder ein nicht parenthesierter Klassenmitglied-Zugriff (5.2.5) ist, ist decltype(e) der Typ der Entität, die von e genannt wird. Wenn es keine solche Entität gibt oder wenn e eine Menge von überladenen Funktionen nennt, ist das Programm nicht formgerecht;
  2. Andernfalls, wenn e ein x-Wert ist, ist decltype(e) T&&, wobei T der Typ von e ist;
  3. Andernfalls, wenn e ein l-Wert ist, ist decltype(e) T&, wobei T der Typ von e ist;
  4. ansonsten ist decltype(e) der Typ von e.

Welcher Typ ist durch decltype(0 + 0) angegeben?

Punkt 1 trifft nicht zu, 2 könnte zutreffen, aber wenn nicht, dann trifft 3 nicht zu und 4 wäre das Ergebnis. Was ist also ein X-Wert, und ist 0 + 0 ein X-Wert?

§3.10p1:

Ein xvalue (ein "eXpiring"-Wert) bezieht sich ebenfalls auf ein Objekt, das in der Regel kurz vor dem Ende seiner Lebensdauer steht (so dass z. B. seine Ressourcen verschoben werden können). Ein xvalue ist das Ergebnis bestimmter Arten von Ausdrücken, die rvalue-Referenzen beinhalten (8.3.2).

Ich sehe in §8.3.2 nichts, was hier hilfreich wäre, aber ich weiß, dass "0 + 0" keine rvalue-Referenzen beinhaltet. Das Literal 0 ist ein prvalue, das heißt "ein rvalue, der kein xvalue ist" (§3.10p1). Ich glaube, "0 + 0" ist auch ein prvalue. Wenn das wahr ist, wäre "decltype(0 + 0)" int (nicht int&&).

Habe ich bei meiner Interpretation etwas übersehen? Ist dieser Code wohlgeformt?

decltype(0 + 0) x;  // Not initialized.

Der Code kompiliert auf GCC 4.7.0 20110427 und Clang 2.9 (trunk 126116). Er wäre nicht wohlgeformt, wenn der Decltype z. B. einen int&&-Typ angeben würde.

10voto

rlc Punkte 2778

0 + 0 ist ein Ausdruck mit zwei Werten (n3290 Abs. 3.10), der die eingebaute operator+ was nach 13,6/12 LR operator+(L,R) die also eine Funktion ist, die etwas zurückgibt, das kein Verweis ist. Das Ergebnis des Ausdrucks ist also auch ein pr-Wert (gemäß 3.10).

Das Ergebnis von 0 + 0 ist also ein pr-Wert, 0 ist ein int Daher ist das Ergebnis von 0 + 0 ein int

5voto

Khaled Nassar Punkte 884

Es ist definitiv ein int:

#include <iostream>
#include <typeinfo>

template<typename T>
struct ref_depth
{
        enum { value = 0 };
};

template<typename T>
struct ref_depth<T&>
{
        enum { value = 1 };
};

template<typename T>
struct ref_depth<T&&>
{
        enum { value = 2 };
};

int main() {

  std::cout
    << "int: " << typeid(int).name() << "\n"
       "decltype(0 + 0): " << typeid(decltype(0 + 0)).name() << "\n"
       "int&&: " << typeid(int&&).name() << "\n";
  std::cout 
    << "ref_depth: int: " << ref_depth<int>::value << "\n"
       "ref_depth: decltype(0 + 0): " << ref_depth<decltype(0 + 0)>::value << "\n"
       "ref_depth: int&&: " << ref_depth<int&&>::value << "\n";

}

Sortie :

int: i
decltype(0 + 0): i
int&&: i
ref_depth: int: 0
ref_depth: decltype(0 + 0): 0
ref_depth: int&&: 2

2voto

orlp Punkte 106335

Ihre Argumentation ist richtig. Ein Ausdruck, der nur Konstanten enthält, ist selbst eine Konstante. Also

decltype(0 + 0) x;

ist gleich

decltype(0) x;

was gleichbedeutend ist mit

int x;

2voto

Ben Voigt Punkte 268424

Ab 5.19 [expr.const] jeder wörtlicher konstanter Ausdruck ist ein Pr-Wert.

A wörtlicher konstanter Ausdruck ist ein Ausdruck der Kernkonstante prvalue vom Typ Literal, aber nicht vom Typ Pointer. Ein ganzzahliger konstanter Ausdruck ist ein literaler konstanter Ausdruck vom Typ Integral oder unscoped enumeration.

Daher gilt Regel 4 für alle literalen konstanten Ausdrücke.

0voto

GCC sagt int -

Código:

#include <iostream>
#include <typeinfo>

int
main ()
{
  int n;
  decltype(0 + 0) x;
  std::cout << "Type of `n': " << typeid(n).name() << std::endl;
  std::cout << "Type of `x': " << typeid(x).name() << std::endl;
}

Sortie :

i

i

Edit: Nach Punkt 4 macht es Sinn, aber ich kann nicht mit Sicherheit sagen, dass Punkt 2 nicht tatsächlich zutrifft. Soweit ich das beurteilen kann, wird 0 + 0 zu 0 ausgewertet, und der Typ von 0 ist int und ist somit der deklarierte Typ.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X