Можно ли создать вектор, заполненный нулями размера N, используя метапрограммирование шаблонов в С++ 11

Я узнаю больше о метапрограммировании шаблонов на С++, и после стандартного создания простых чисел и факториала во время компиляции я теперь пытаюсь создать класс Matrix во время компиляции. Подзадача этого состоит в том, чтобы создать вектор размера N, заполненный нулями. Возможно ли это сделать с помощью метапрограммирования шаблонов?

Я думаю что-то вроде этого.

template<int N>
struct Vec {
    static std::vector<int> vec;

    constexpr Vec(int count) {
        for (int i = 0; i < count; ++i) {
            vec.push_back(0); 
        }
    }
};

Но компилятор говорит, что «циклы for» не разрешены в конструкторе constexpr. Есть ли способ добиться такой функциональности во время компиляции.


person ObjectsFirst    schedule 11.05.2019    source источник
comment
Почему Vec принимает целочисленный параметр шаблона и имеет конструктор с целочисленным аргументом? Также вам действительно нужна статическая неконстантная переменная?   -  person Martin Bonner supports Monica    schedule 11.05.2019
comment
std::array твой друг здесь.   -  person George    schedule 11.05.2019


Ответы (2)


Подзадача этого состоит в том, чтобы создать вектор размера N, заполненный нулями. Возможно ли это сделать с помощью метапрограммирования шаблонов?

Если под «вектором» вы имеете в виду именно «std::vector», нет: это невозможно в С++ 11, С++ 14 или С++ 17. Возможно, с будущими версиями стандарта; не сейчас.

Если для «вектора» вы принимаете «std::array», да: это возможно и тривиально просто (функция инициализации не требуется)

constexpr std::array<int, 10> a{};  // zero initialized !

Я полагаю, что ваше Vec могло быть написано

template <std::size_t N> // better std::size_t for a size (IMHO)
struct Vec
 {
   std::array<int, N> vec; // no static for a member, please

   constexpr Vec () : vec{}
    { }
};

но мне кажется, что вы можете использовать напрямую std::array.

Но компилятор говорит, что «циклы for» не разрешены в конструкторе constexpr. Есть ли способ добиться такой функциональности во время компиляции.

Компилятор жалуется на проблему другого типа: он говорит, что в C++11 функция constexpr не может содержать цикл for.

В C++11 функция constexpr может содержать (значительно упрощая) только инструкцию return. Конструктор constexpr должен быть пустым; только список инициализации.

Если вам нужна более сложная функция constexpr (с циклом for), вам понадобится C++14.

person max66    schedule 11.05.2019

Я написал поверх основного:

constexpr size_t N = 100;
constexpr std::vector<int> ZEROES(N, 0);

Что привело к выводу, что:

7:39: error: the type 'const std::vector<int>' of constexpr variable 'ZEROES' is not literal
In file included from /usr/include/c++/4.9/vector:64:0,
                 from 4:
/usr/include/c++/4.9/bits/stl_vector.h:214:11: note: 'std::vector<int>' is not literal because:
     class vector : protected _Vector_base<_Tp, _Alloc>
           ^
/usr/include/c++/4.9/bits/stl_vector.h:214:11: note:   'std::vector<int>' has a non-trivial destructor

Это означает, что вы не сможете создать время компиляции std::vector любого типа. Однако вы можете создать массив, я не знаю, поможет ли это:

constexpr int ZEROES2[N] = {0};
person Notinlist    schedule 11.05.2019