#include <type_traits>
template<typename T>
struct A {
static_assert(!std::is_same_v<int, T>);
};
template<typename T>
struct B {
void foo() {
A<int>{};
}
};
int main() {
}
Почему эта программа компилируется gcc и msvc (1 и 2), но не компилируется clang (3)? Должна ли она компилироваться в соответствии со стандартом?
Формально - Clang неправ, код должен компилироваться. Так как foo
нигде не используется, она не должна инстантинироваться.
Следовательно, A<int>
тоже не должен инстантинироваться, и static_assert
не должен срабатывать.
Но вообще, по духу стандарта код должен быть ill-formed, no diagnostic required (что означало бы, что код невалиден, и что все три компилятора соответствуют стандарту) из-за вот этого раздела:
8 The validity of a template may be checked prior to any instantiation. [ Note: Knowing which names are type names allows the syntax of every template to be checked in this way. — end note ] The program is ill-formed, no diagnostic required, if:
(8.1) — no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or
...
(emphasis mine)
То есть если код в шаблоне некорректен для абсолютно всех возможных наборов шаблонных аргументов, то программа невалидна (но сообщение об ошибке не гарантируется).
foo
невалидна для всех T
, но так как сама foo()
- не шаблон, к ней этот раздел не применяется.
Почему я говорю "по духу стандарта"?
Существует:
Section: 17.8 [temp.spec] Status: drafting Submitter: Nikolay Ivchenkov Date: 2011-03-06
Many statements in the Standard apply only to templates, for example, 17.7 [temp.res] paragraph 8:
If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.
This clearly should apply to non-template member functions of class templates, not just to templates per se. Terminology should be established to refer to these generic entities that are not actually templates.
(Спасибо @StoryTeller.)
Которая как раз утверждает, что разделы вроде [temp.res]/8.1
должны применяться не только к шаблонам, но и нешаблонным членам шаблонных классов и т. п.
Судя по
Status: drafting
Комитет согласен, что это нужно исправить, но с конкретными изменениями в текст стандарта по этой теме они пока не определились.
Нет, не должна. В таком случае (определение структуры) нужна обязательная инстанциация. Однако стандарт разрешает не диагностировать подобную ошибку, если вызова не произошло (т.к. это потенциально замедляет компиляцию). Так что все правы, но clang более строг, как обычно.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Почему мне не выдает ошибок при определении, ведь оператор -> должен возвращать указатель или класс, у которого есть -> ?
Прочитал статьи, смотрю видео и заметил вот такую конструкцию:
Как использовать scheduled аннотация из спринга?допустим есть какой то метод который удаляет данные из БД MYSQL можно ли сделать так что с помощю...