Reputation: 1168
I have a regular class, let's call it Handler
, which performs some algorithm invoked on demand in runtime.
The algorithm reads an array (m_arr
), its content is known at compile-time so I want to utilize constexpr
to initialize it.
I don't want an aggregate initializer (it might look ugly), I'd like to use a function which initializes the array.
For the sake of elegance and encapsulation I want to keep them as Handler
's static members. The m_arr
I'd like to qualify constexpr
itself, because I want to init another array with another function basing on it (if I succeed with this one in the first place).
Currently I'm struggling with four propagating errors. This is a draft of what I'm trying to achieve (with errors marked):
#include <array>
class Handler
{
static const int SIZE = 20;
static constexpr std::array<int, SIZE> initArr();
static constexpr std::array<int, SIZE> m_arr; //C2737 'private: static std::array<int, SIZE> const Handler::m_arr': 'constexpr' object must be initialized
//much other non-const stuff which this class handles...
};
constexpr std::array<int, Handler::SIZE> Handler::m_arr = Handler::initArr(); //C2131 expression did not evaluate to a constant
constexpr std::array<int, Handler::SIZE> Handler::initArr()
{
std::array<int, SIZE> arr; //C3250 'arr': declaration is not allowed in 'constexpr' function body
arr[0] = int(2); //C3249 illegal statement or sub-expression for 'constexpr' function
arr[1] = int(7); //C3249 illegal statement or sub-expression for 'constexpr' function
arr[2] = int(4); // -- || --
//...
return arr;
}
Apparently I'm doing something wrong here - or - I expect from the language something which it cannot provide (compiler - MSVC 2015/14.0).
Explanation of the reason of the errors (along with a closest working alternative) very very appreciated...
Upvotes: 1
Views: 317
Reputation: 20559
Generally speaking, static functions in classes cannot be used to initialize constexpr
static data members because the function definitions are not considered at the point of initialization. You need to make it a free function and initialize the data member in the class body:
constexpr std::array<int, SIZE> init()
{
// ...
}
struct C {
static constexpr std::array<int, SIZE> arr = init();
};
Upvotes: 1