Этот код работает на GCC, но не clang.
class Base
{
static constexpr int PRIVATE = 1;
};
struct Derived : public Base
{
template <class T>
int bar( T & t )
{
return PRIVATE;
}
};
int main()
{
Derived d;
int i = 3;
d.bar(i);
}
Ссылка Godbolt: https://godbolt.org/g/qPJ47p
В случае частной функции-члена GCC правильно обнаруживает попытку доступа к частному члену, если функция шаблона создается, но в противном случае нет. Clang обнаруживает попытку, даже когда функция шаблона никогда не создается.
Однако при использовании частной статической переменной constexpr GCC (до последнего 8.1) не может остановить частный доступ, даже если создается функция шаблона. Кланг правильно (?) Жалуется.
Вопрос: какой из двух компиляторов соответствует стандарту в этой ситуации?
Мне кажется, что GCC не может быть прав, разрешая доступ к частной статической переменной constexpr. Но в то же время это не похоже на слишком сложную проблему, но она не находится в последнем GCC: это делает ее преднамеренной.
Большое спасибо paxdiablo за его ясный и тщательный ответ. Согласно его предложению, я сделал более полный список тестовых примеров и сузил его до static
спецификатора, вызывающего проблему для GCC. См. Эту ссылку Godbolt для получения более подробной информации: https://godbolt.org/g/A3zCLk
Comparison of GCC and Clang:
Private member | GCC | Clang
static const | accept | reject
static constexpr | accept | reject
static | accept | reject
const | instantiate | reject
no-specifiers | instantiate | reject
static function | instantiate | reject
function | instantiate | reject
("instantiate" means GCC rejects it upon template instantiation)