decltype

This is a good article. Click here for more information.
Source: Wikipedia, the free encyclopedia.

In the

expression. Introduced in C++11, its primary intended use is in generic programming, where it is often difficult, or even impossible, to express types that depend on template
parameters.

As generic programming techniques became increasingly popular throughout the 1990s, the need for a type-deduction mechanism was recognized. Many compiler vendors implemented their own versions of the operator, typically called typeof, and some portable implementations with limited functionality, based on existing language features were developed. In 2002, Bjarne Stroustrup proposed that a standardized version of the operator be added to the C++ language, and suggested the name "decltype", to reflect that the operator would yield the "declared type" of an expression.

decltype's semantics were designed to cater to both generic library writers and novice programmers. In general, the deduced type matches the type of the object or function exactly as declared in the source code. Like the sizeof[1] operator, decltype's operand is not evaluated.

Motivation

With the introduction of

expression, commonly referred to as typeof, was recognized. In generic programming, it is often difficult or impossible to express types that depend on template parameters,[2][3] in particular the return type of function template instantiations.[2]

Many vendors provide the typeof operator as a compiler extension.

C++0x, Koenig and Moo predicted that "decltype will be widely used to make everyday programs easier to write."[8]

In 2002, Bjarne Stroustrup suggested extending the C++ language with mechanisms for querying the type of an expression, and initializing objects without specifying the type.[2] Stroustrup observed that the reference-dropping semantics offered by the typeof operator provided by the GCC and EDG compilers could be problematic.[2] Conversely, an operator returning a reference type based on the lvalue-ness of the expression was deemed too confusing. The initial proposal to the C++ standards committee outlined a combination of the two variants; the operator would return a reference type only if the declared type of the expression included a reference. To emphasize that the deduced type would reflect the "declared type" of the expression, the operator was proposed to be named decltype.[2]

One of the cited main motivations for the decltype proposal was the ability to write perfect

trailing-return-type:[9]

int& foo(int& i);
float foo(float& f);

template <class T> auto transparent_forwarder(T& t) > decltype(foo(t)) {
  return foo(t);
}

decltype is essential here because it preserves the information about whether the wrapped function returns a reference type.[10]

Semantics

Similarly to the sizeof operator, the operand of decltype is unevaluated, so expressions like decltype(i++) will not result in an increment of the variable i.[11] Informally, the type returned by decltype(e) is deduced as follows:[2]

  1. If the expression e refers to a variable in local or namespace scope, a static member variable or a function parameter, then the result is that variable's or parameter's declared type
  2. Otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e; if e is an xvalue, the result is T&&; otherwise, e is a prvalue and the result is T.
  3. As a special case,
    decltype(auto) allows for type deduction like auto
    but it preserves the value category of the initializer. More specifically, it is equivalent to decltype(initializer).

These semantics were designed to fulfill the needs of generic library writers, while at the same time being intuitive for novice programmers, because the return type of decltype always matches the type of the object or function exactly as declared in the source code.[2] More formally, Rule 1 applies to unparenthesized id-expressions and class member access expressions.[12][13] Example:[12] Note for added lines for bar(). Below the type deduced for "bar()" is plain int, not const int, because prvalues of non-class types always have cv-unqualified types, despite the statically declared different type.

const int&& foo();
const int bar();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1; // type is const int&&
decltype(bar()) x2; // type is int
decltype(i) x3; // type is int
decltype(a->x) x4; // type is double
decltype((a->x)) x5; // type is const double&

The reason for the difference between the latter two invocations of decltype is that the parenthesized expression (a->x) is neither an id-expression nor a member access expression, and therefore does not denote a named object.[14] Because the expression is an lvalue, its deduced type is "reference to the type of the expression", or const double&.[11] The fact that extra parentheses introduce a reference qualifier to the type can be a source of errors for programmers who do not fully understand decltype.[15]

In December 2008, a concern was raised to the committee by Jaakko Järvi over the inability to use decltype to form a qualified-id,

C++0x, the Japanese ISO member body noted that "a scope operator(::) cannot be applied to decltype, but it should be. It would be useful in the case to obtain member type(nested-type) from an instance as follows:[17]

vector<int> v;
decltype(v)::value_type i = 0; // int i = 0;

This, and similar issues pertaining to the wording inhibiting the use of decltype in the declaration of a

destructor call, were addressed by David Vandevoorde, and voted into the working paper in March 2010.[18][19]

Availability

decltype is included in the C++ Language Standard since

References

  1. ^ a b Miller, William M. (2009-09-29). "C++ Standard Core Language Active Issues, Revision 66". ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2009-10-03.
  2. ^ a b c d e f g Gregor, Douglas; Järvi, Jaakko; Siek, Jeremy; Stroustrup, Bjarne (2003-04-28). "Decltype and auto" (PDF). ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2015-08-28.
  3. ^ Kalev, Danny (2008-05-08). "Clean Up Function Syntax Mess with decltype". DevX.com. Retrieved 2009-09-04.
  4. ^ a b c Gibbons, Bill (2000-11-01). "A Portable "typeof" Operator". Dr. Dobb's Journal. Retrieved 2009-09-03.
  5. ^ a b Alexandrescu, Andrei (2000-10-01). "Generic<Programming>: Mappings between Types and Values". Dr. Dobb's Journal. Retrieved 2009-09-03.
  6. ^ a b Koenig, Andrew; Barbara E. Moo (2002-02-01). "C++ Made Easier: Naming Unknown Types". Dr. Dobb's Journal. Retrieved 2009-09-03.
  7. ^ Dewhurst, Steve (2000-08-01). "Common Knowledge: A Bitwise typeof Operator, Part 1". Dr. Dobb's Journal. Retrieved 2009-09-03.
  8. ^ Koenig, Andrew; Barbara E. Moo (2011-07-19). "4 Useful New Features in C++0x". Dr. Dobb's Journal. Retrieved 2012-01-12.
  9. ^ a b c Dos Reis, Gabriel; Järvi, Jaakko; Stroustrup, Bjarne (2004-10-12). "Decltype and auto (revision 4)" (PDF). ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2009-09-04.
  10. ^ a b c "decltype Operator". Microsoft Corporation. Retrieved 2009-09-04.
  11. ^ a b Dos Reis, Gabriel; Järvi, Jaakko; Stroustrup, Bjarne (2007-07-18). "Decltype (revision 7): proposed wording" (PDF). ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2009-09-04.
  12. ^ a b c Becker, Pete. "Working Draft, Standard for Programming Language C++" (PDF). ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2009-09-04.
  13. ^ Miller, William M. (2009-08-03). "C++ Standard Core Language Defect Reports, Revision 65". ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2009-09-15.
  14. ^ Miller, William M. (2009-08-03). "C++ Standard Core Language Closed Issues, Revision 65". ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2009-09-04.
  15. ^ Mazières, David (June 2021). "C++ value categories and decltype demystified". Retrieved 2022-06-16.
  16. ^ Dos Reis, Gabriel; Järvi, Jaakko; Stroustrup, Bjarne (2006-11-05). "Decltype (revision 6): proposed wording" (PDF). ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2009-10-03.
  17. ^ Miller, William M. (2009-08-03). "C++ CD1 Comment Status". ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2009-10-03.
  18. ^ Miller, William M. (2010-03-29). "C++ Standard Core Language Defect Reports, Revision 69". ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2010-04-10.
  19. ^ Vandevoorde, Daveed (2010-02-03). "Core issues 743 and 950: Additional decltype(...) uses" (PDF). ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee. Retrieved 2010-04-10.
  20. ^ "C++0x Support in GCC". Free Software Foundation. 2009-08-27. Retrieved 2009-09-04.
  21. ^ "GCC 4.3 Release Series". Free Software Foundation. 2009-08-13. Retrieved 2009-09-04.
  22. ^ "Type Specifier decltype (C++0x)". Embarcadero Technologies. Archived from the original on 2011-07-08. Retrieved 2009-09-04.
  23. Intel Corporation
    . Retrieved 2009-09-04.
  24. ^ Gregor, Douglas (2011-01-26). "New C++0x feature support in Clang". Archived from the original on 2011-01-30.

External links