2017-02-19 27 views
2

Скорее всего один не хочет, чтобы этот пример компиляции:«Статическая функция член переопределяет виртуальную функцию базового класса» пойманной НКУ и лязгом, но не VC++

#include <iostream> 

class C { 
public: 
    virtual void Foo() { 
     std::cout << "From C\n"; 
    } 
}; 

class D : public C { 
public: 
    static void Foo() { 
     std::cout << "From D\n"; 
    } 
}; 

int main() { 
    D d; 
    d.Foo(); 
    return 0; 
} 

Это не компилируется действительно в НКУ и clang (Ошибка «Статическая функция-член переопределяет виртуальную функцию в базовом классе»). Однако он компилируется в Visual C++, вызывая От D до консоли при запуске. Даже с последним компилятором VC++ RC 2017 (v141) с опциями ISO C++. Последний проект стандарта (/ std: C++ latest) и /permissive- (link) включен.

Какой компилятор прав? Является ли эта ошибка стандартом? Если да, значит ли это, что VC++ не соответствует стандарту в этом случае?

+1

Я уверен, что это незаконно. Скорее всего, ошибка MSVC. Кроме того, версия компилятора обычно представляет собой MSVC14.1 или более конкретно 19.10.24930 при моей установке. – tambre

ответ

3

Это определенно ошибка MSVC. ISO C++ этого не позволяет.

class.static.mfct/2 (курсив мой):

[Примечание: Статическая функция-член не имеет этот указатель. - end note] Статическая функция-член не должна быть виртуальной. Там не должно быть статическим и не-статические функции члена с тем же именем и типов же параметров ([over.load]) ...

+1

«Неформованный» не означает, что «не следует компилировать». Для определения языка требуется, чтобы компилятор выдал диагностику. Я не видел упоминания о том, что происходит с этим кодом. –

+0

@PeteBecker, Noted; и исправлены. Благодарю. :-). Я все еще учился быть педантичным с этими стандартными терминами. – WhiZTiM

+0

Ваш акцент делается на перегрузке, но 'C :: Foo' не участвует в перегрузке, находясь в отдельной области, если только не введен с использованием C :: Foo;' в 'D'. Если 'C :: Foo' не был виртуальным,' static D :: Foo' просто спрячет его. – w1ck3dg0ph3r

1

10,3: 2 утверждает, что D::Foo должен быть виртуальным (даже если это не объявлено).

Если виртуальная функция-член VF объявляется в базовом классе и в класса Derived, полученного непосредственно или косвенно из базы, член функции ФЖ с таким же названием, параметр типа-списка (8.3. 5), cv-qualification и ref-qualifier (или отсутствие такого же), что и Base :: vf , тогда Derived :: vf также является виртуальным (независимо от того, объявлено ли оно ), и он переопределяет 111 Base :: ... Ф.

И 9.4.1: 2 утверждает, что она не может быть VI rtual

[Примечание: статическая функция-член не имеет указателя (9.3.2). -end note] Статическая функция-член не должна быть виртуальной. Там должно быть не быть статическим и нестационарным членом с тем же именем и теми же типами параметров (13.1). Статическая функция-член должна не объявляться const, volatile или const volatile.

 Смежные вопросы

  • Нет связанных вопросов^_^