Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Placeholder type specifiers(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
       

      A placeholder type specifier designates aplaceholder type that will be replaced later, typically by deduction from aninitializer.

      Contents

      [edit]Syntax

      type-constraint (optional)auto (1)
      type-constraint (optional)decltype(auto) (2)(since C++14)
      type-constraint -(since C++20) aconcept name, optionally qualified, optionally followed by a template argument list enclosed in<>
      1) Type is deduced using the rules fortemplate argument deduction.
      2) Type isdecltype(expr), whereexpr is the initializer or the operands used inreturn statements.

      The placeholderauto may be accompanied by modifiers, such asconst or&, which will participate in the type deduction.The placeholderdecltype(auto) must be the sole constituent of the declared type.(since C++14)

      Iftype-constraint is present, letT be the type deduced for the placeholder, thetype-constraint introduces aconstraint expression as follows:

      • Iftype-constraint isConcept<A1, ..., An>, then the constraint expression isConcept<T, A1, ..., An>;
      • otherwise (type-constraint isConcept without an argument list), the constraint expression isConcept<T>.

      Deduction fails if the constraint expression is invalid or returnsfalse.

      (since C++20)

      [edit]Explanation

      A placeholder type specifier may appear in the following contexts:

      Parameter declarations

      In the following parameter declarations, the type of the parameter declared can be of syntax(1):

      • If a parameter of alambda expression has a placeholder type, the lambda expression is a generic lambda.
      (since C++14)
      (since C++17)
      (since C++20)

      [edit]Function declarations

      A placeholder type can appear in thedeclaration specifiers for afunction declarator that includes a trailing return type.

      A placeholder type can appear in the declaration specifiers ortype specifiers in the declared return type of afunction declarator.Return type deduction will be applied in this case.

      (since C++14)
      auto f()->int;// OK: f returns intauto g(){return0.0;}// OK since C++14: g returns doubleauto h();// OK since C++14: h’s return type will be deduced when it is defined

      [edit]Variable declarations

      The type of a variable declared using a placeholder type is deduced from itsinitializer. This use is allowed in an initializing declaration of a variable.

      The placeholder type can only appear as one of thedeclaration specifiers in the declaration specifier sequence or as one of the type specifiers in a trailing return type that specifies the type that replaces such a declaration specifier. In this case, the declaration must declare at least one variable, and each variable must have a non-empty initializer.

      // “auto”s in declaration specifiersauto x=5;// OK: x has type intconstauto*v=&x, u=6;// OK: v has type const int*, u has type const intstaticauto y=0.0;// OK: y has type double auto f()->int;auto(*fp)()->auto= f;// OK: the “auto” in the trailing return type// can be deduced from f

      Structured binding declarations

      Theauto specifier can be used in astructured binding declaration.

      (since C++17)

      [edit]new expressions

      A placeholder type can be used in the type specifier sequence of the type-id of anew expression. In such a type-id, the placeholder type must appear as one of the type specifiers in the type specifier sequence or a trailing return type that specifies the type that replacessuch a type specifier.

      Function-style cast

      Theauto type specifier can be used as the type specifier of afunction-style cast.

      (since C++23)

      [edit]Notes

      Until C++11,auto had the semantic of astorage duration specifier.

      A program that uses a placeholder type in a context not explicitly stated above is ill-formed.

      If a declaration declares multiple entities, and the declaration specifier sequence uses a placeholder type, the program is ill-formed if any of the following conditions is satisfied:

      • Some of the entities declared are not variables.
      • The type that replaces the placeholder type is not the same in each deduction.
      auto f()->int, i=0;// Error: declares a function and a variable with “auto”auto a=5, b={1,2};// Error: different types for “auto”

      If a function or variable with an unreplaced placeholder type is referenced by an expression, the program is ill-formed.

      auto v=1;auto l=[&]{    v++;return l;// Error: The placeholder type for l was not replaced};std::function<void()> p=[&]{    v++;return p;// OK};

      Theauto keyword may also be used in a nested name specifier. A nested name specifier of the formauto:: is a placeholder that is replaced by a class or enumeration type following the rules forconstrained type placeholder deduction.

      (concepts TS)
      Feature-test macroValueStdFeature
      __cpp_decltype_auto201304L(C++14)decltype(auto)

      [edit]Keywords

      auto,decltype

      [edit]Example

      Run this code
      #include <iostream>#include <utility> template<class T,class U>auto add(T t, U u){return t+ u;}// the return type is the type of operator+(T, U) // perfect forwarding of a function call must use decltype(auto)// in case the function it calls returns by referencetemplate<class F,class...Args>decltype(auto) PerfectForward(F fun, Args&&...args){return fun(std::forward<Args>(args)...);} template<auto n>// C++17 auto parameter declarationauto f()->std::pair<decltype(n), decltype(n)>// auto can't deduce from brace-init-list{return{n, n};} int main(){auto a=1+2;// type of a is intauto b= add(1,1.2);// type of b is double    static_assert(std::is_same_v<decltype(a),int>);    static_assert(std::is_same_v<decltype(b),double>); auto c0= a;// type of c0 is int, holding a copy of a    decltype(auto) c1= a;// type of c1 is int, holding a copy of a    decltype(auto) c2=(a);// type of c2 is int&, an alias of astd::cout<<"before modification through c2, a = "<< a<<'\n';++c2;std::cout<<" after modification through c2, a = "<< a<<'\n'; auto[v, w]= f<0>();//structured binding declaration auto d={1,2};// OK: type of d is std::initializer_list<int>auto n={5};// OK: type of n is std::initializer_list<int>//  auto e{1, 2};    // Error as of DR n3922, std::initializer_list<int> beforeauto m{5};// OK: type of m is int as of DR n3922, initializer_list<int> before//  decltype(auto) z = { 1, 2 } // Error: {1, 2} is not an expression // auto is commonly used for unnamed types such as the types of lambda expressionsauto lambda=[](int x){return x+3;}; //  auto int x; // valid C++98, error as of C++11//  auto x;     // valid C, error in C++ [](...){}(c0, c1, v, w, d, n, m, lambda);// suppresses "unused variable" warnings}

      Possible output:

      before modification through c2, a = 3 after modification through c2, a = 4

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 1265C++11theauto specifier could be used to declare a function with a trailing
      return type and define a variable in one declaration statement
      prohibited
      CWG 1346C++11a parenthesized expression list could not be assigned to anauto variableallowed
      CWG 1347C++11a declaration with theauto specifier could define two variables
      with typesT andstd::initializer_list<T> respectively
      prohibited
      CWG 1852C++14theauto specifier indecltype(auto) was also a placeholdernot a placeholder
      in this case
      CWG 1892C++11the return type of a function pointer type-id could beautoprohibited
      CWG 2476C++11the resolution ofCWG issue 1892 prohibited the deduction
      of the return type of function pointer variables from initializers
      allowed
      N3922C++11direct-list-initialization ofauto deducesstd::initializer_listill-formed for more than one
      elements, deduce element
      type for single element

      [edit]References

      • C++23 standard (ISO/IEC 14882:2024):
      • 9.2.9.6 Placeholder type specifiers [dcl.spec.auto]
      • C++20 standard (ISO/IEC 14882:2020):
      • 9.2.8.5 Placeholder type specifiers [dcl.spec.auto]
      • C++17 standard (ISO/IEC 14882:2017):
      • 10.1.7.4 Theauto specifier [dcl.spec.auto]
      • C++14 standard (ISO/IEC 14882:2014):
      • 7.1.6.4auto specifier [dcl.spec.auto]
      • C++11 standard (ISO/IEC 14882:2011):
      • 7.1.6.4auto specifier [dcl.spec.auto]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/auto&oldid=183007"

      [8]ページ先頭

      ©2009-2025 Movatter.jp