Can std::array be used in a constexpr class?
Solution 1
Because std::array<T, N>
is an aggregate, it can be initialized as a constexpr
if and only if the underlying type T
has a constexpr
constructor (when presented with each initializer you provide).
Solution 2
Based on the comment by @MarkGlisse: this compiles
#include <array>
#include <iostream>
template<typename T, std::size_t N>
struct X
{
constexpr X(const std::array<T,N>& a):arr(a){}
private:
std::array<T,N> arr;
};
constexpr std::array<int,2> a {{ 13, 18 }};
constexpr X<int,2> x = a;
int main()
{
}
I believe I have found the relevant quote from the Standard here:
12.1 Constructors [class.ctor]
6 A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odrused (3.2) to create an object of its class type (1.8) or when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement. If that user-written default constructor would be ill-formed, the program is ill-formed. If that user-written default constructor would satisfy the requirements of a constexpr constructor (7.1.5), the implicitly-defined default constructor is constexpr.
This looks essentially like @BenVoigt's answer.
Vincent
Researcher, astrophysicist, computer scientist, programming language expert, software architect and C++ standardization committee member. LinkedIn: https://www.linkedin.com/in/vincent-reverdy
Updated on January 11, 2020Comments
-
Vincent over 4 years
I am currently creating a class with a
constexpr
constructor and I wonder if I can use anstd::array
to store the data of this class. Does the standard explicitly specify that anstd::array
has aconstexpr
constructor and that its contents can be accessed at compile-time ? -
Marc Glisse over 11 years
#include <cstdlib> #include <array> template<typename T, std::size_t N> struct X { constexpr X(std::array<T,N>& a):arr(a){} private: std::array<T,N> arr; }; std::array<int,2> a = { 13, 18 }; X<int,2> x = a;
compiles for me... -
TemplateRex over 11 years@MarcGlisse Try adding
constexpr
in front ofa
andX
, and it won't compile! -
Marc Glisse over 11 years
#include <cstdlib> #include <array> template<typename T, std::size_t N> struct X { constexpr X(const std::array<T,N>& a):arr(a){} private: std::array<T,N> arr; }; constexpr std::array<int,2> a = { 13, 18 }; constexpr X<int,2> x = a;
compiles just fine. -
TemplateRex over 11 years@MarcGlisse OK, tnx, so any clue why it compiles? ;-)
-
Marc Glisse over 11 yearschris said it, std::array is an aggregate. What part exactly confuses you?