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

Я узнаю больше о шаблонном метапрограммировании на c ++, и после выполнения стандартной генерации простых чисел и факториала во время компиляции я сейчас пытаюсь создать класс 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-loop не разрешены в конструкторе constexpr. Есть ли способ достичь такой функциональности во время компиляции.

Ответы [ 2 ]

2 голосов
/ 11 мая 2019

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

Если под «вектором» подразумевается именно «std::vector», нет: невозможно в C ++ 11, C ++ 14 или C ++ 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-loops» не являютсяразрешено в конструкторе constexpr.Есть ли способ достичь такой функциональности во время компиляции?

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

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

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

1 голос
/ 11 мая 2019

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

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