Как сделать псевдоним типа в зависимости от константы времени компиляции в классе? - PullRequest
2 голосов
/ 29 марта 2019

Я хочу написать класс, который использует числовую квадратуру. Квадратурный порядок определяет размер некоторых контейнеров, которые я буду использовать. Я хотел бы сделать псевдоним типа для таких контейнеров, и он должен зависеть от квадратурного порядка.

Следующий код показывает мои испытания. Это кажется неоптимальным в том смысле, что я должен повторить порядок в определении псевдонима типа:

#include <array>

class Quadrature
{
public:

        static constexpr unsigned int getOrder()
        {
                return 3;
        }

        // This line doesn't compile!
        //
        // using WeightsContainer = std::array<double, getOrder()>;
        //
        // g++ says "error: 'static constexpr unsigned int Quadrature::getOrder()'
        // called in a constant expression before its definition is complete"

        // This line compiles, but repeats the order. :-(
        using WeightsContainer = std::array<double, 3>;

private:

        WeightsContainer container;
};

Одно решение, которое я нашел, представляет параметр шаблона Order. Но на самом деле я хотел определить квадратурный порядок, и введение параметра шаблона сделало бы его переменным.

Есть ли возможность сделать заказ постоянной времени компиляции и использовать его в моем определении псевдонима типа?

Edit:

Для полноты я мог бы, конечно, использовать определение препроцессора. Но это чувствует себя старомодным. : -)

Редактировать 2:

Хорошо, я нашел другую возможность. Я мог бы добавить функцию вне области видимости этого класса:

constexpr unsigned int order()
{
    return 3;
}

Но это не так, потому что это свойство класса и, следовательно, должно быть в рамках класса!

1 Ответ

1 голос
/ 29 марта 2019

Одна вещь, которую вы можете сделать, это переместить значение в переменную-член:

class Quadrature
{
private:
        static constexpr unsigned int _order = 3;
public:
        static constexpr unsigned int getOrder()
        {
                return _order;
        }    
        using WeightsContainer = std::array<double, _order>;

        // ...
};

Если вам нужны более сложные вычисления вместо return 3, в C ++ 17 вы можете использовать лямбду, как упомянуто @Quentin:

class Quadrature
{
public:
        static constexpr auto getOrder = []()
        {
            return ...;
        };
        using WeightsContainer = std::array<double, getOrder()>;

        // ...
};

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...