Я немного искал трюк с индексами, чтобы увидеть, с чем я могу пойти, и наткнулся на странную ошибку ... Во-первых, простые не-старые индексы:Неожиданный непостоянный 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...>
{};
Я создал время компиляции класса массив, полученный из std::initializer_list
и имел его индексируемой (предположим, что N3471 поддержка вашим компилятором. это будет в следующем стандарте в любом случае). Вот оно:
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];
}
};
Итак, я попытался создать функцию, которая возвращает копию array
после добавления 1 к каждому из своих членов:
template<typename T, std::size_t... I>
auto constexpr add_one(const array<T>& a, indices<I...>)
-> const array<T>
{
return { (a[I]+1)... };
}
И чтобы закончить с кодом, вот мой главный:
int main()
{
constexpr array<int> a = { 1, 2, 3 };
constexpr auto b = add_one(a, make_indices<a.size()>());
return 0;
}
Я не думаю, что код компилируется в любом случае, но я очень удивлен сообщением об ошибке (Вот ideone код):
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
Итак, может кто-нибудь объяснить мне, что именно не является достаточно постоянным для компилятора в приведенном выше коде?
EDIT: прослеживаний для этого вопроса
- Is it legal to declare a constexpr std::initializer_list object?
- Confusion about constant expression
Истеризатор A *, равный или равный *, не является выражением и может, как таковое никогда не быть постоянным выражением, является тем, что, по моему мнению, является проблемой здесь. – Xeo
Фактически, Clang 3.2 отклоняет даже инициализацию 'a' –
@AndyProwl Я знаю, Clang не поддерживает N3471, вот почему :) – Morwenn