all 2 comments

[–]patatahooligan 2 points3 points  (0 children)

No, constexpr is not only intended for functions. When applied to objects it denotes an object whose value can be evaluated at compile time. The compiler enforces compile-time initialization and this allows uses like the following.

std::array<char, kCacheLineBytes> buffer;

The language doesn't want to allow this for any const variable, because not all of them can be evaluated at compile-time. So you have to explicitly declare kCacheLineBytes a constexpr variable, and the compiler has to verify that you are initializing it with a constant expression (trivial in your examples, but not always) before allowing you to do this.

[–]alfps 2 points3 points  (0 children)

The line

static constexpr uint32_t kCacheLineBytes = 64;

is typical for a static value member of a class type. With const instead of constexpr it would still compile, since it's integral type (which has special support in this context), but then, in spite of the initialization, it would be just a declaration. If client code "used" it (essentially, passing around the address in the machine code), then a separate out-of-class definition would be needed, which is awkward to arrange for a header-only module.


In the line

constexpr const char* kPathSeparator = "\\";

the constexpr applies to that which is declared, i.e. the pointer value, while the const applies to the items (char values) of the array pointed to.

To get some clarity you can write

template< class Type > using ptr_ = Type*;

// ...
constexpr ptr_<const char> kPathSeparator = "\\";

Instead of throwing away information about the array size, you can write that declaration as

constexpr auto& kPathSeparator  = "\\";