constexpr关键词

本文围绕C++11中的constexpr specifier展开,介绍其可使变量或函数值用于常量表达式,能在编译时求值。阐述了constexpr变量和函数需满足的要求,如类型、初始化等条件,还提及constexpr构造函数的相关规定,并给出计算阶乘的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://en.cppreference.com/w/cpp/language/constexpr

constexpr specifier (since C++11)

constexpr - specifies that the value of a variable or function can appear in constant expressions

      constant expressions : Defines an expression that can be evaluated at compile time.

Explanation

The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time.

Such variables and functions can then be used where only compile time constant expressions are allowed (provided that appropriate function arguments are given)

A constexpr specifier used in an object declaration implies const; A constexpr specifier used in a function declaration implies inline.

If any declaration of a function or function template has a constexpr specifier, then every declaration must contain that specifier.

 

constexpr variable must satisfy the following requirements:

constexpr function must satisfy the following requirements:

  • its return type (if any) must be a LiteralType
  • each of its parameters must be a LiteralType
  • or constructor , the class must have no virtual base classes
  • there exists at least one set of argument values such that an invocation of the function could be an evaluated subexpression of a core constant expression.No diagnostic is required for a violation of this bullet.

constexpr constructor whose function body is not =delete; must satisfy the following additional requirements:

  • every constructor selected to initializing non-static data members and base class must be a constexpr constructor.

For constexpr function templates and constexpr member functions of class templates, at least one specialization must satisfy the abovementioned requirements. Other specializations are still considered as constexpr, even though a call to such a function cannot appear in a constant expression.

 

Constexpr constructors are permitted for classes that aren't literal types. For example, the default constructor of std::unique_ptr is constexpr, allowing constant initialization.

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

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

Example

Definition of a C++11 constexpr function which computes factorials and a literal type that extends string literals:

#include <iostream>
#include <stdexcept>
 
// C++11 constexpr functions use recursion rather than iteration
// (C++14 constexpr functions may use local variables and loops)
constexpr int factorial(int n)
{
    return n <= 1 ? 1 : (n * factorial(n - 1));
}
 
// literal class
class conststr {
    const char* p;
    std::size_t sz;
public:
    template<std::size_t N>
    constexpr conststr(const char(&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 ?:
    constexpr char operator[](std::size_t n) const
    {
        return n < sz ? p[n] : throw std::out_of_range("");
    }
    constexpr std::size_t size() const { return sz; }
};
 
// C++11 constexpr functions had to put everything in a single return statement
// (C++14 doesn't have that requirement)
constexpr std::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);
}
 
// output function that requires a compile-time constant, for testing
template<int n>
struct constN
{
    constN() { std::cout << n << '\n'; }
};
 
int main()
{
    std::cout << "4! = " ;
    constN<factorial(4)> out1; // computed at compile time
 
    volatile int k = 8; // disallow optimization using volatile
    std::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
}

Output:

4! = 24
8! = 40320
the number of lowercase letters in "Hello, world!" is 9

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值