I have a class template for an N-dimensional array:
template<typename T, std::size_t... Shape>
class ndarray { ... };
One consequence of this template design is that there is an additional 'implicit' template parameter if you will: std::size_t Size
, the product of all arguments in Shape
. I have been using a C++17 fold expression ((1 * ... * Shape)
) where I would typically use Size
if it weren't dependent on Shape
, but I'm wondering if adding the following 'alias' would result in any subtle differences in the compiled assembly:
template<typename T, std::size_t... Shape>
class ndarray {
static constinit std::size_t Size = (1 * ... * Shape);
...
};
Interestingly, the ISO C++20 standard doesn't state whether or not constinit
implies inline
as it does for constexpr
and consteval
. I think the semantics of constinit
(especially in relation to constexpr
variables) only really makes sense if the variable were also inline
, but its omission from the standard makes me wary of this conclusion.
constinit
has exactly and only one semantic: the expression used to initialize the variable must be a constant expression.
That's it. That's all it does: it causes a compile error if the initializing expression isn't a valid constant expression. In every other way, such a variable is identical to not having constinit
there. Indeed, the early versions of the proposal had constinit as an attribute rather than a keyword, since it didn't really do anything. It only gave a compile error for invalid initialization of the variable.
For this case, there is no reason not to make the variable constexpr
. You clearly don't intend to change the variable, so there's no point in making the variable modifiable.
No, these are not at all the same because constinit
doesn't make the variable const
. As such, the initialization of Size
isn't even valid. Writing constinit const
is mostly equivalent to writing constexpr
, which is semantically equivalent to the constant fold-expression. There's no guarantee that any compiler does treat them identically, but in most constant-expression cases there isn't much room for variation.
constinit
also doesn't imply inline
: it isn't that the standard "doesn't state whether", it's just that there's nothing to say. Since there's no point in putting constinit
and constexpr
on the same variable, it's not clear what semantics you expect in that area.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With