为什么 class::class::class::staticClassMember() 编译(在 C++ 中)?

Why class::class::class::staticClassMember() compiles (in C++)?

我一定是遗漏了 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:: 的任何计数都是允许的。

这不仅仅是一个理论问题。我想在存在子 class 的情况下使用 SFINAE 和条件编译。在基础 class 与子 class:

同名之前工作正常
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
}

我的问题分为两部分:

那就是 。您可以通过在 SFINAE 条件句中简单地使用 std::is_same_v<T, typename T::SubClass> 来验证它不是 T

template <class T>
auto callWorkout() -> std::enable_if_t<!std::is_same_v<T, typename T::SubClass>>
{ T::SubClass::workout(); }

如果您不需要 SFINAE(因为您不想控制重载解析),那么带有描述性自定义消息的 static_assert 也可以很好地完成。