为什么在C语言中class::class::class::staticClassMember()这样的长尾词式能编译?

2026-04-16 18:234阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计429个文字,预计阅读时间需要2分钟。

为什么在C语言中class::class::class::staticClassMember()这样的长尾词式能编译?

我曾在C语言规范中犯了一些错误,因为无法理解为什么以下代码能成功编译:cclass MyClass{ static void fun() { }};

int main(){ MyClass::MyClass::MyClass::fun();}有人能指出我的标准还是只是解释一下语言吗?

我一定错过了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编译)

为什么在C语言中class::class::class::staticClassMember()这样的长尾词式能编译?

这是 injected class name of MyClass.你可以通过简单地使用std :: is_same_v< T,typename T :: SubClass>来验证它不是T.在SFINAE有条件的.

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

如果您不需要SFINAE(因为您没有尝试控制重载决策),那么带有描述性自定义消息的static_assert也可以很好地完成.

本文共计429个文字,预计阅读时间需要2分钟。

为什么在C语言中class::class::class::staticClassMember()这样的长尾词式能编译?

我曾在C语言规范中犯了一些错误,因为无法理解为什么以下代码能成功编译:cclass MyClass{ static void fun() { }};

int main(){ MyClass::MyClass::MyClass::fun();}有人能指出我的标准还是只是解释一下语言吗?

我一定错过了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编译)

为什么在C语言中class::class::class::staticClassMember()这样的长尾词式能编译?

这是 injected class name of MyClass.你可以通过简单地使用std :: is_same_v< T,typename T :: SubClass>来验证它不是T.在SFINAE有条件的.

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

如果您不需要SFINAE(因为您没有尝试控制重载决策),那么带有描述性自定义消息的static_assert也可以很好地完成.