Mi stavo un po 'trastullando con il trucco degli indici per vedere dove potevo andare e mi sono imbattuto in uno strano errore ... In primo luogo, i chiari indici non così vecchi:Inatteso non costante std :: initializer_list
template<std::size_t...>
struct indices {};
template<std::size_t N, std::size_t... Indices>
struct make_indices:
make_indices<N-1, N-1, Indices...>
{};
template<std::size_t... Indices>
struct make_indices<0, Indices...>:
indices<Indices...>
{};
ho creato una classe gamma di compilazione derivato da un std::initializer_list
e aveva essa indicizzabili (scontato che N3471 è il supporto per il compilatore. sarà nel prossimo standard comunque). Eccolo:
template<typename T>
struct array:
public std::initializer_list<T>
{
constexpr array(std::initializer_list<T> values):
std::initializer_list<T>(values)
{}
constexpr auto operator[](std::size_t n)
-> T
{
return this->begin()[n];
}
};
Così, ho cercato di creare una funzione che restituisce una copia di un array
dopo l'aggiunta di 1 a ciascuno dei suoi membri:
template<typename T, std::size_t... I>
auto constexpr add_one(const array<T>& a, indices<I...>)
-> const array<T>
{
return { (a[I]+1)... };
}
e per finire con il codice, qui è il mio principale:
int main()
{
constexpr array<int> a = { 1, 2, 3 };
constexpr auto b = add_one(a, make_indices<a.size()>());
return 0;
}
non pensavo che il codice avrebbe compilato in ogni caso, ma io sono molto sorpreso dal messaggio di errore (Ecco il ideone codice):
In function 'int main()':
error: 'const smath::array<int>{std::initializer_list<int>{((const int*)(& const int [3]{2, 3, 4})), 3u}}' is not a constant expression
Quindi, qualcuno potrebbe spiegarmi cosa non è esattamente abbastanza costante per il compilatore nel codice precedente?
EDIT: follow-up per questa domanda
- Is it legal to declare a constexpr std::initializer_list object?
- Confusion about constant expression
Un inizializzatore * brace-or-equal * non è un'espressione e in quanto tale non può mai essere un'espressione costante, è quello che ritengo sia il problema qui. – Xeo
In effetti, Clang 3.2 rifiuta anche l'inizializzazione di 'a' –
@AndyProwl Lo so, Clang non supporta N3471, ecco perché :) – Morwenn