Constexpr и шаблоны: ошибка компилятора? - PullRequest
0 голосов
/ 05 февраля 2019

Следующее работает как ожидалось:

#include <array>
constexpr std::array<int, 3> values = {1, 2, 3};
template <int i> struct A { static constexpr int val = values[i]; };
int main() { A<1> a; }

Однако я получаю ошибку компилятора от компилятора MSVC, если мы используем values.size() в качестве параметра шаблона:

int main() { A<values.size()> a; }

Ошибкаis выражение не оценивается как константа .GCC компилируется без ошибок.

  • Это ошибка компилятора MSVC?
  • Существует ли стандартный / умный способ обойти эту ошибку?

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

MSVC прав.Не может быть неопределенного поведения в любом контексте constexpr.Или же это не константное выражение.

Строка:

int main() { A<values.size()> a; }

В основном:

constexpr auto i = values[values.size()];

Что вне пределов.Фактически MSVC правильно диагностирует ошибку:

example.cpp
<source>(3): error C2131: expression did not evaluate to a constant
C:/msvc/v19_16/include\array(187): note: failure was caused by out of range index 3; allowed range is 0 <= index < 3
<source>(4): note: see reference to class template instantiation 'A<3>' being compiled 
<source>(2): note: see reference to class template instantiation 'std::array<int,3>' being compiled
Compiler returned: 2

С другой стороны, и GCC, и MSVC принимают этот код:

int main() { A<values.size() - 1> a; }
0 голосов
/ 05 февраля 2019

Это на самом деле ошибка / недостаток GCC, а не MSVC.

A<values.size()> a;

заставляет вас получить доступ к values вне диапазона, поскольку действительные индексы [0, size()).MSVC выдает ошибку, что не может этого сделать, потому что это неопределенное поведение, и это не допускается в константном выражении.

Обратите внимание, что clang также правильно диагностирует это и выдает ошибку: https://godbolt.org/z/vmi86S

...