std::array jako constexpr

0

Witam
Poniższy kod się kompiluje dla kompilatora obsługującego C++14. Jeżeli zamienię linijkę z "i" na "tab[i] = i" to wtedy przestaje się kompilować. Jeżeli usunę constexpr to oczywiście też się kompiluje. Jeżeli owrapuję std:array w jakąś strukturę która ma konstruktor constexpr i przyjmuje parametr array to też dalej się wywala na "tab[i]". Czy da radę coś tu poprawić by móc generować tablice o rozmiarze N w czasie kompilacji?

#include <iostream>
#include <array>

using namespace std;

template<unsigned N>
constexpr array<unsigned, N> zwrocArray()
{
    array<unsigned, N> tab{ 0 };
    for (unsigned i = 0; i<N; ++i)
        i; //tab[i] = i; //kompiluje się, ale jak dam tab[i] = i to już nie kompiluje się czyli nie działa wywoływanie zwrocArray w czasie kompilacji.

    return tab;
}

int main()
{
    constexpr array<unsigned, 30> tab = zwrocArray<30>();

    return 0;
}
1
#include <iostream>
#include <array>
#include <utility>

namespace detail {

template<typename T, std::size_t N, std::size_t... Vs>
constexpr std::array<T, N> make_array_impl(std::integer_sequence<T, Vs...>) {
    return {{Vs...}};
}

}

template<typename T, std::size_t N, typename Values = std::make_integer_sequence<T, N>>
constexpr std::array<T, N> make_array()
{
    return detail::make_array_impl<T, N>(Values{});
}

int main()
{
    constexpr auto tab = make_array<unsigned, 30>();
    std::cout << tab[5] << '\n';
}

Jeśli koniecznie C++14. W C++17 łatwiej to załatwić folding'iem.

0

Jeszcze takie coś po googlowaniu wymyśliłem i static_assertem udowodnić się da, że alokuje w trakcie kompilacji, ale nie wiem tutaj jak przeiterować i wyprintować tablice w runtimie. x[0] się zgadza (abstrahując już od tego że od końca) ale x[1] i następne już wskazują na jakieś śmieci.

// Example program
#include <iostream>
#include <string>

template<int N>
struct NestedStruct
{
  int x;
  NestedStruct<N-1> next;
  constexpr NestedStruct<N>() : x(N) {} //to musze dać by typ był Literalny
};

template<>
struct NestedStruct<0> 
{
  int x;
  constexpr NestedStruct<0>() : x(0) {} //to musze dać by typ był Literalny
};

template<int N>
struct Lista
{
    constexpr Lista() 
    {
    };
    NestedStruct<N-1> f;
};

int main()
{
  constexpr Lista<10> lista;
  static_assert(lista.f.x == 9, "NOK");
  
  const int* x = &lista.f.x; //to nie pomaga, x[0] zwraca 9 ale x[1] itp smieci
  std::cout << x[1] << std::endl;
  
  return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1