43 votes

Pourquoi std :: declval ajoute une référence?

std::declval est au moment de la compilation de l'utilitaire utilisé pour construire une expression dans le but de déterminer son type. Il est défini comme ceci:

template< class T >
typename std::add_rvalue_reference<T>::type declval() noexcept;

Ne serait-ce pas plus simple à la place?

template< class T >
T declval() noexcept;

Quel est l'avantage d'une référence de type de retour? Et ne devrait-elle pas être appelés declref?

Les premiers exemple historique qui je trouve est n2958, qui appelle la fonction value() mais déjà renvoie toujours une référence.

Remarque, l'opérande de decltype n'a pas besoin d'avoir un accessible destructeur, c'est à dire qu'il n'est pas sémantiquement vérifié qu'une expression.

template< typename t >
t declprval() noexcept;

class c { ~ c (); };
decltype ( declprval< c >() ) * p = nullptr; // OK

37voto

T.C. Points 22510

Le "non temporaire est mise en place pour la fonction en retournant prvalue de type d'objet en decltype" règle s'applique uniquement si l'appel de la fonction elle-même est soit l'opérande de decltype ou l'opérande de droite d'un opérateur virgule que l'opérande decltype (§5.2.2 [expr.appel]/p11), ce qui signifie que la donnée d' declprval dans l'OP,

template< typename t >
t declprval() noexcept;

class c { ~ c (); };

int f(c &&);

decltype(f(declprval<c>())) i;  // error: inaccessible destructor

ne compile pas. Plus généralement, le retour T permettrait d'éviter la plupart des non-trivial utilise des declval incomplète de types, de type privé, destructeurs, et la comme:

class D;

int f(D &&);

decltype(f(declprval<D>())) i2;  // doesn't compile. D must be a complete type

et a peu d'intérêt dans la mesure xvalues sont pratiquement indiscernables de prvalues sauf lorsque vous utilisez decltype sur eux, et vous n'utilisez pas habituellement decltype directement sur la valeur de retour de l' declval - vous connaissez le type déjà.

12voto

6502 Points 42700

Les tableaux ne peuvent pas être renvoyés par valeur, donc même la simple déclaration d'une fonction renvoyant un tableau par valeur n'est pas un code valide.

Vous pouvez cependant renvoyer un tableau par référence.

4voto

Manu343726 Points 8803

Le but de l' decltype() est d'avoir une expression qui agit comme une valeur valide de type T, pour le dire en tant que T dans les expressions attendent Ts. Le problème, c'est qu'en C++, un type Tpeut être non-copiable, ou même par défaut non-constructible. Donc, en utilisant l' T{} pour cet effet ne fonctionne pas.

Ce decltype() n'est de retourner une rvalue-référence à un T. Référence rvalue devrait être valable pour n'importe quel type d' T, de sorte que ses garanties que nous avons un valide T de référence rvalue d' T, et une garantie que nous puissions avoir une référence rvalue à tout type T. C'est le truc.

Pensez - decltype() comme "donnez-moi une expression valide de type T". Bien sûr, son utilisation est prévue pour la résolution de surcharge, de type de détermination, etc; puisque son but est de retourner une expression valide (Dans le sens syntaxique), de ne pas retourner une valeur. C'est reflété dans le fait qu' std::declval() n'est pas du tout défini, sa seule déclaré.
Si elle a été définie, nous avons le problème initial à nouveau (Nous avons à construire une valeur d'un type arbitraire T, et ce n'est pas possible).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X