Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      constexpr 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
      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
       

      Contents

      [edit]Explanation

      Theconstexpr specifier declares that it is possible to evaluate the value of the entities at compile time. Such entities can then be used where only compile timeconstant expressions are allowed (provided that appropriate function arguments are given).

      Aconstexpr specifier used in an object declaration or non-static member function(until C++14) impliesconst.

      Aconstexpr specifier used in the first declaration of a function orstatic data member(since C++17) impliesinline. If any declaration of a function or function template has aconstexpr specifier, then every declaration must contain that specifier.

      [edit]constexpr variable

      A variable or variable template(since C++14) can be declaredconstexpr if all following conditions are satisfied:

      (until C++26)
      (since C++26)

      • It has constant destruction, which means one of the following conditions needs to be satisfied:
      • It is not of class type nor (possibly multi-dimensional) array thereof.
      • It is of a class type with aconstexpr destructor or (possibly multi-dimensional) array thereof, and for a hypothetical expressione whose only effect is to destroy the object,e would be acore constant expression if the lifetime of the object and its non-mutable subobjects (but not its mutable subobjects) were considered to start withine.

      If aconstexpr variable is nottranslation-unit-local, it should not be initialized to refer to a translation-unit-local entity that is usable in constant expressions, nor have a subobject that refers to such an entity. Such initialization is disallowed in amodule interface unit (outside itsprivate module fragment, if any) or a module partition, and is deprecated in any other context.

      (since C++20)

      [edit]constexpr function

      A function or function template can be declaredconstexpr.

      A function isconstexpr-suitable if all following conditions are satisfied:

      • If it is a constructor or destructor(since C++20), its class does not have anyvirtual base class.
      (until C++20)
      • Its return type (if exists) is aliteral type.
      • Each of its parameter types is a literal type.
      (until C++23)
      (since C++20)
      • Its function body is=default,= delete, or a compound statementenclosing only the following:
      (until C++14)
      • Its function body is=default,= delete, or a compound statement that(until C++20) doesnotenclose the following:
      • goto statements
      • statements withlabels other thancase anddefault
      (until C++20)
      • definitions of variables of non-literal types
      • definitions of variables of static or threadstorage duration
      (since C++14)
      (until C++23)

      Except for instantiatedconstexpr functions, non-templatedconstexpr functions must be constexpr-suitable.

      For a non-constructorconstexpr function that is neither defaulted nor templated, if no argument values exist such that an invocation of the function could be an evaluated subexpression of acore constant expression, the program is ill-formed, no diagnostic required.

      For a templatedconstexpr function, if no specialization of the function/class template would make the templated function constexpr-suitable when considered as a non-templated function, the program is ill-formed, no diagnostic required.

      (until C++23)

      An invocation of aconstexpr function in a given context produces the same result as an invocation of an equivalent non-constexpr function in the same context in all respects, with the following exceptions:

      [edit]constexpr constructor

      On top of the requirements ofconstexpr functions, a constructor also needs to satisfy all following conditions to be constexpr-suitable:

      • Its function body is= delete or satisfies the following additional requirements:
      • If the class is aunion having variant members, exactly one of them is initialized.
      • If the class is aunion-like class, but is not a union, for each of its anonymous union members having variant members, exactly one of them is initialized.
      • Every non-variant non-static data member and base class subobject is initialized.
      (until C++20)
      • If the constructor is adelegating constructor, the target constructor is aconstexpr constructor.
      • If the constructor is a non-delegating constructor, every constructor selected to initialize non-static data members and base class subobjects is aconstexpr constructor.
      (until C++23)

      For aconstexpr constructor that is neither defaulted nor templated, if no argument values exist such that an invocation of the function could be an evaluated subexpression of the initialization full-expression of some object subject toconstant expression, the program is ill-formed, no diagnostic required.

      (until C++23)

      [edit]constexpr destructor

      Destructors cannot beconstexpr, but atrivial destructor can be implicitly called in constant expressions.

      (until C++20)

      On top of the requirements ofconstexpr functions, a destructor also needs to satisfy all following conditions to be constexpr-suitable:

      • For every subobject of class type or (possibly multi-dimensional) array thereof, that class type has aconstexpr destructor.
      (until C++23)
      • The class does not have any virtual base class.
      (since C++20)

      [edit]Notes

      Because thenoexcept operator always returnstrue for a constant expression, it can be used to check if a particular invocation of a constexpr function takes the constant expression branch:

      constexprint f();constexprbool b1=noexcept(f());// false, undefined constexpr functionconstexprint f(){return0;}constexprbool b2=noexcept(f());// true, f() is a constant expression
      (until C++17)

      It is possible to write a constexpr function whose invocation can never satisfy the requirements of a core constant expression:

      void f(int& i)// not a constexpr function{    i=0;} constexprvoid g(int& i)// well-formed since C++23{    f(i);// unconditionally calls f, cannot be a constant expression}
      (since C++23)

      Constexpr constructors are permitted for classes that are not literal types. For example, the default constructor ofstd::shared_ptr is constexpr, allowingconstant initialization.

      Reference variables can be declared constexpr (their initializers have to bereference constant expressions):

      staticconstexprintconst& x=42;// constexpr reference to a const int object// (the object has static storage duration//  due to life extension by a static reference)

      Even thoughtry blocks and inline assembly are allowed in constexpr functions, throwing exceptionsthat are uncaught(since C++26) or executing the assembly is still disallowed in a constant expression.

      If a variable has constant destruction, there is no need to generate machine code in order to call destructor for it, even if its destructor is not trivial.

      A non-lambda, non-special-member, and non-templated constexpr function cannot implicitly become an immediate function. Users need to explicitly mark itconsteval to make such an intended function definition well-formed.

      (since C++20)
      Feature-test macroValueStdFeature
      __cpp_constexpr200704L(C++11)constexpr
      201304L(C++14)Relaxedconstexpr,non-constconstexpr methods
      201603L(C++17)Constexpr lambda
      201907L(C++20)Trivialdefault initialization andasm-declaration inconstexpr functions
      202002L(C++20)Changing the active member of a union in constant evaluation
      202110L(C++23)Non-literal variables, labels, andgoto statements in constexpr functions
      202207L(C++23)Relaxing someconstexpr restrictions
      202211L(C++23)Permittingstaticconstexpr variables inconstexpr functions
      202306L(C++26)Constexpr cast fromvoid*: towards constexpr type-erasure
      __cpp_constexpr_in_decltype201711L(C++11)
      (DR)
      Generation of function and variable definitions whenneeded for constant evaluation
      __cpp_constexpr_dynamic_alloc201907L(C++20)Operations for dynamic storage duration inconstexpr functions

      [edit]Keywords

      constexpr

      [edit]Example

      Defines C++11/14constexpr functions that compute factorials; defines a literal type that extends string literals:

      Run this code
      #include <iostream>#include <stdexcept> // C++11 constexpr functions use recursion rather than iterationconstexprint factorial(int n){return n<=1?1:(n* factorial(n-1));} // C++14 constexpr functions may use local variables and loops#if __cplusplus >= 201402Lconstexprint factorial_cxx14(int n){int res=1;while(n>1)        res*= n--;return res;}#endif // C++14 // A literal classclass conststr{constchar* p;std::size_t sz;public:template<std::size_t N>constexpr conststr(constchar(&a)[N]): p(a), sz(N-1){} // constexpr functions signal errors by throwing exceptions// in C++11, they must do so from the conditional operator ?:constexprchar operator[](std::size_t n)const{return n< sz? p[n]:throwstd::out_of_range("");} constexprstd::size_t size()const{return sz;}}; // C++11 constexpr functions had to put everything in a single return statement// (C++14 does not have that requirement)constexprstd::size_t countlower(conststr s,std::size_t n=0,std::size_t c=0){return n== s.size()? c:'a'<= s[n]&& s[n]<='z'? countlower(s, n+1, c+1): countlower(s, n+1, c);} // An output function that requires a compile-time constant, for testingtemplate<int n>struct constN{    constN(){std::cout<< n<<'\n';}}; int main(){std::cout<<"4! = ";    constN<factorial(4)> out1;// computed at compile time volatileint k=8;// disallow optimization using volatilestd::cout<< k<<"! = "<< factorial(k)<<'\n';// computed at run time std::cout<<"The number of lowercase letters in\"Hello, world!\" is ";    constN<countlower("Hello, world!")> out2;// implicitly converted to conststr constexprint a[12]={0,1,2,3,4,5,6,7,8};constexprint length_a= sizeof a/ sizeof(int);// std::size(a) in C++17,// std::ssize(a) in C++20std::cout<<"Array of length "<< length_a<<" has elements: ";for(int i=0; i< length_a;++i)std::cout<< a[i]<<' ';std::cout<<'\n';}

      Output:

      4! = 248! = 40320The number of lowercase letters in "Hello, world!" is 9Array of length 12 has elements: 0 1 2 3 4 5 6 7 8 0 0 0

      [edit]Defect reports

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

      DRApplied toBehavior as publishedCorrect behavior
      CWG 1358C++11templatedconstexpr functions also needed
      to have at least one valid argument value
      no need
      CWG 1359C++11constexpr union constructors
      must initialize all data members
      initializes exactly one data
      member for non-empty unions
      CWG 1366C++11classes withconstexpr constructors whose function bodies
      are=default or= delete could have virtual base classes
      such classes can neither
      have virtual base classes
      CWG 1595C++11constexpr delegating constructors required
      all involved constructors to beconstexpr
      only requires the target
      constructor to beconstexpr
      CWG 1712C++14aconstexpr variable template was required to have
      all its declarations contain theconstexpr specifier[1]
      not required anymore
      CWG 1911C++11constexpr constructors for non-literal types were not allowedallowed in constant initialization
      CWG 2004C++11copy/move of a union with a mutable member
      was allowed in a constant expression
      mutable variants disqualify
      implicit copy/move
      CWG 2022C++98whether equivalentconstexpr and non-constexpr
      function produce equal result might depend
      on whether copy elision is performed
      assume that copy elision is always
      performed in constant expressions
      CWG 2163C++14labels were allowed inconstexpr functions
      even thoughgoto statements are prohibited
      labels also prohibited
      CWG 2268C++11copy/move of a union with a mutable member was
      prohibited by the resolution ofCWG issue 2004
      allowed if the object is created
      within the constant expression
      CWG 2278C++98the resolution ofCWG issue 2022 was not implementableassume that copy elision is never
      performed in constant expressions
      CWG 2531C++11a non-inline variable became inline
      if it is redeclared withconstexpr
      the variable does
      not become inline
      1. It is redundant because there cannot be more than one declaration of a variable template with theconstexpr specifier.

      [edit]See also

      constant expression defines anexpression that can be evaluated at compile time
      consteval specifier(C++20) specifies that a function is animmediate function, that is, every call to the function must be in a constant evaluation[edit]
      constinit specifier(C++20) asserts that a variable has static initialization, i.e.zero initialization andconstant initialization[edit]
      C documentation forconstexpr
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/constexpr&oldid=179324"

      [8]ページ先頭

      ©2009-2025 Movatter.jp