В следующем коде используется член перечисления m
в качестве постоянного выражения, то есть в качестве параметра шаблона. Код компилируется под gcc, но не под clang (live demo). Кланг говорит: «ошибка: аргумент шаблона непигового типа не является постоянным выражением».Использование перечисления в качестве постоянного выражения. Какой компилятор прав?
Проблема может быть решена путем замены строки // 1
на A<tst<p>::m> a
. Поэтому мой вопрос заключается не в том, как исправить эту проблему, но какой компилятор прав.
template<size_t n> struct A{};
template<size_t n>
struct tst
{ enum : size_t { m= n % 15 };
template<size_t p>
void
call(tst<p> const &t2) {
A<t2.m> a; // 1
}
};
[Настоящие ссылки говорят] (http://en.cppreference.com/w/cpp/language/enum) «Когда перечисление с незащищенным доступом является членом класса, его счетчики могут быть доступны с помощью операторов доступа к членам класса' .' и '->' ". Тем не менее, он ничего не говорит о постоянстве выражений. –
@JoachimPileborg Стандарт '§ 7.2.2' действительно говорит' Идентификаторы в списке нумераторов объявляются как константы и могут появляться там, где требуются константы. ' – lcs