Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      decltype specifier(since C++11)

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      const/volatile
      decltype(C++11)
      auto(C++11)
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
      Declarations
       

      Inspects the declared type of an entity or the type and value category of an expression.

      Contents

      [edit]Syntax

      decltype (entity) (1)
      decltype (expression) (2)

      [edit]Explanation

      1) If the argument is an unparenthesizedid-expression or an unparenthesizedclass member access expression, then decltype yields the type of theentity named by this expression. If there is no such entity, or if the argument names a set of overloaded functions, the program is ill-formed.

      If the argument is an unparenthesizedid-expression naming astructured binding, then decltype yields thereferenced type (described in the specification of the structured binding declaration).

      (since C++17)

      If the argument is an unparenthesizedid-expression naming aconstant template parameter, then decltype yields the type of the template parameter (after performing any necessary type deduction if the template parameter is declared with a placeholder type). The type is non-const even if the entity is a template parameter object (which is a const object).

      (since C++20)
      2) If the argument is any other expression of typeT, and
      a) if thevalue category ofexpression isxvalue, then decltype yieldsT&&;
      b) if the value category ofexpression islvalue, then decltype yieldsT&;
      c) if the value category ofexpression isprvalue, then decltype yieldsT.

      Ifexpression is a function call which returns a prvalue of class type or is acomma expression whose right operand is such a function call, a temporary object is not introduced for that prvalue.

      (until C++17)

      Ifexpression is a prvalue other than a (possibly parenthesized)immediate invocation(since C++20), a temporary object is notmaterialized from that prvalue: such prvalue has no result object.

      (since C++17)
      Because no temporary object is created, the type need not becomplete or have an availabledestructor, and can beabstract. This rule doesn't apply to sub-expressions: indecltype(f(g())),g() must have a complete type, butf() need not.

      Note that if the name of an object is parenthesized, it is treated as an ordinary lvalue expression, thusdecltype(x) anddecltype((x)) are often different types.

      decltype is useful when declaring types that are difficult or impossible to declare using standard notation, like lambda-related types or types that depend on template parameters.

      [edit]Notes

      Feature-test macroValueStdFeature
      __cpp_decltype200707L(C++11)decltype

      [edit]Keywords

      decltype

      [edit]Example

      Run this code
      #include <cassert>#include <iostream>#include <type_traits> struct A{double x;};const A* a; decltype(a->x) y;// type of y is double (declared type)decltype((a->x)) z= y;// type of z is const double& (lvalue expression) template<typename T,typename U>auto add(T t, U u)-> decltype(t+ u)// return type depends on template parameters// return type can be deduced since C++14{return t+ u;} constint& getRef(constint* p){return*p;}static_assert(std::is_same_v<decltype(getRef),constint&(constint*)>);auto getRefFwdBad(constint* p){return getRef(p);}static_assert(std::is_same_v<decltype(getRefFwdBad),int(constint*)>,"Just returning auto isn't perfect forwarding.");decltype(auto) getRefFwdGood(constint* p){return getRef(p);}static_assert(std::is_same_v<decltype(getRefFwdGood),constint&(constint*)>,"Returning decltype(auto) perfectly forwards the return type."); // Alternatively:auto getRefFwdGood1(constint* p)-> decltype(getRef(p)){return getRef(p);}static_assert(std::is_same_v<decltype(getRefFwdGood1),constint&(constint*)>,"Returning decltype(return expression) also perfectly forwards the return type."); int main(){int i=33;    decltype(i) j= i*2;    static_assert(std::is_same_v<decltype(i), decltype(j)>);assert(i==33&&66== j); auto f=[i](int av,int bv)->int{return av* bv+ i;};auto h=[i](int av,int bv)->int{return av* bv+ i;};    static_assert(!std::is_same_v<decltype(f), decltype(h)>,"The type of a lambda function is unique and unnamed");     decltype(f) g= f;std::cout<< f(3,3)<<' '<< g(3,3)<<'\n';}

      Output:

      42 42

      [edit]References

      Extended content
      • C++23 standard (ISO/IEC 14882:2024):
      • 9.2.9.5 Decltype specifiers [dcl.type.decltype]
      • C++20 standard (ISO/IEC 14882:2020):
      • 9.2.8.4 Decltype specifiers [dcl.type.decltype]
      • C++17 standard (ISO/IEC 14882:2017):
      • TBD Decltype specifiers [dcl.type.decltype]
      • C++14 standard (ISO/IEC 14882:2014):
      • TBD Decltype specifiers [dcl.type.decltype]
      • C++11 standard (ISO/IEC 14882:2011):
      • TBD Decltype specifiers [dcl.type.decltype]
      This section is incomplete
      Reason: Requires correction. See:Talk: Wrong References.

      [edit]See also

      auto specifier(C++11) specifies a type deduced from an expression[edit]
      (C++11)
      obtains a reference to an object of the template type argument for use in an unevaluated context
      (function template)[edit]
      (C++11)
      checks if two types are the same
      (class template)[edit]
      C documentation fortypeof
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/decltype&oldid=182734"

      [8]ページ先頭

      ©2009-2025 Movatter.jp