Я, должно быть, что-то пропустил в спецификации C ++, потому что не могу объяснить, почему следующий код успешно компилируется:
class MyClass { static void fun(); };
int main() { MyClass::MyClass::MyClass::fun(); }
Может ли кто-нибудь указать мне на стандарт или просто объяснить мне семантику? Я предполагаю, что только один MyClass::
разрешен. Два MyClass::MyClass::
должны вызвать ошибку. Экспериментируя с MS Visual C ++ 2017 и GNU C ++ 6.2.0, я понял, что допускается любое число MyClass::
.
Это не только теоретический вопрос. Я хотел использовать SFINAE и компиляцию условий с существованием подкласса. Работали хорошо, пока базовый класс не имел того же имени, что и подкласс:
template <class T> void callWorkout() { T::SubClass::workout(); }
struct X { struct SubClass { static void workout(); }; };
struct Y { /*empty*/ };
struct SubClass { static void workout(); };
int main() {
callWorkout<X>(); // works fine - compiled
callWorkout<Y>(); // works "fine" - not compiled, no SubClass in Y
callWorkout<SubClass>(); // ooops? - still compiled, there is no 'SubClass' in SubClass
}
Мой вопрос состоит из двух частей:
- Какова точная семантика
MyClass::MyClass::
?
- Как исправить приведенный выше пример, чтобы не компилировать
callWorkout<SubClass>()
? (Я пытался добавить sizeof(typename T::SubClass)
, но на удивление он компилируется и для T=SubClass
)