статическая цепочка инициализации constexpr внутри класса - PullRequest
1 голос
/ 05 октября 2019

У меня есть обычный класс, назовем его Handler, который выполняет некоторый алгоритм, вызываемый по требованию во время выполнения. Алгоритм читает массив (m_arr), его содержимое известно во время компиляции, поэтому я хочу использовать constexpr для его инициализации.

Мне не нужен агрегатный инициализатор (это может выглядеть уродливо), Я хотел бы использовать функцию, которая инициализирует массив. Ради элегантности и инкапсуляции я хочу сохранить их как статические члены Handler. m_arr Я бы хотел сам квалифицировать constexpr, потому что я хочу инициализировать другой массив с другой базирующейся на нем функцией (если мне это удастся в первую очередь).

В настоящее время я 'Я борюсь с четырьмя распространяющимися ошибками. Это черновик того, чего я пытаюсь достичь (с помеченными ошибками):

#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;
}

Очевидно, я здесь что-то делаю не так - или - я ожидаю от языка то, чего он не может обеспечить (компилятор- MSVC 2015 / 14.0).

Объяснение причины ошибок (наряду с ближайшей рабочей альтернативой) очень, очень ценится ...

1 Ответ

1 голос
/ 05 октября 2019

Вообще говоря, статические функции в классах нельзя использовать для инициализации constexpr членов статических данных, поскольку определения функций не рассматриваются в момент инициализации. Вам нужно сделать его свободной функцией и инициализировать член данных в теле класса:

constexpr std::array<int, SIZE> init()
{
    // ...
}

struct C {
    static constexpr std::array<int, SIZE> arr = init();
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...