Reinterpret использует шаблон не-типа: clang С++ 14 vs С++ 1z

Рассмотрим следующий код:

template <int* > struct foo { };

int main() {
    foo<(int*)42> f;
    (void)f;
}

При компиляции на clang 3.8.0 с -std=c++11 или -std=c++14 программа компилируется. При компиляции с -std=c++1z, это ошибки с:

main.cpp:4:9: error: non-type template argument is not a constant expression
    foo<(int*)42> f;
        ^~~~~~~~

gcc 5.3.0 не компилирует код независимо от режима С++, который, как я считаю, является правильным. В чем разница между clang между С++ 14 и С++ 1z и почему он принимает код? Что-то изменилось в С++ 1z, которое здесь имеет значение?

Ответы

Ответ 1

Использование godbolt показывает, что в режиме -std=c++1z Clang 3.5.1 принимает код, но 3.6.0 отклоняет его. changelog указывает, что эта версия была, когда была добавлена ​​поддержка функций С++ 1z, а именно: "Постоянная оценка для всех аргументов шаблона непигового типа". Я предполагаю, что в режимах С++ 11 и С++ 14 используются правила С++ 11, тогда как режим С++ 1z использует правила проекта С++ 1z/latest. Конечно, тот факт, что программа считается действительной в режиме С++ 11/14, является самой ошибкой.

Вот некоторые сообщения об ошибках с похожими (но не связанными напрямую) случаями:

Ошибка 18043 - разрешить произвольные выражения константы адреса как аргументы шаблона непигового типа в качестве расширения

Ошибка 10398 - Clang не будет принимать константу нулевого указателя как аргумент шаблона непигового

Ошибка 10396 - сбой во время управления именем с параметром шаблона непигового

Ошибка 9700 - Нулевой указатель не принимается как аргумент шаблона непигового