gpt4 book ai didi

c++ - 不一致的完全限定枚举编译时行为

转载 作者:太空狗 更新时间:2023-10-29 23:00:24 26 4
gpt4 key购买 nike

我和一位同事在使用枚举时遇到了一个奇怪的行为。

我们都在使用(大概)相同的 make 文件和相同的编译器 (gcc 4.8.4) 编译同一个项目。唯一的区别是我是一台 Linux 虚拟机,而他在本地 Linux 环境中,但这不应该是问题的根源。

给定以下代码片段

namespace Something
{
enum Something {
DARK_SIDE,
LIGHT_SIDE
}
}

...

Something::Something leEnumVal = Something::Something::DARK_SIDE; // inconsistency here

不一致的是,在我的电脑上出现以下错误:

'Something::Something' is not a class or namespace

但是,在我的同事环境中一切正常。

值得一提的是,我们使用的是QT Creator,在构建过程中可能会产生一些额外的东西。

Ofc,我设法让代码在我的环境中编译,不一致的行变成了:

 Something:Something leEnumVal = Something::DARK_SIDE; // this compiles for both

问题 1:处理枚举值的标准方法是什么?

问题 2:什么会导致编译器处理代码的方式不一致? (我的猜测是我的同事在他的设置中使用了一些 C++ 11 特性,但在开始研究他如何启用它们之前我需要一些确认)

上面使用的代码用于显示我们面临的问题。

考虑到这是一个非常大的项目,使用了许多枚举,我们面临这样的情况:一些开发人员使用第一种方法来寻址枚举值,而另一些开发人员则使用第二种方法。

第一种方法的好处是在自动完成期间仅列出来自限定枚举的值,而不是来自整个命名空间的值(例如第二个)。

考虑到命名空间中有许多枚举,所以人们宁愿选择第一种方法也是有道理的。

最佳答案

在 C++11 之前的 C++ 中,枚举不会为其枚举器(常量)生成新的命名空间。您的原始代码行在旧 C++ 中无效,因为没有命名空间 Something::Something。这是将枚举放在它自己的命名空间中的一个很好的理由:另一种较旧的解决方案是将枚举的名称放在每个枚举器中,例如

enum side {
SIDE_DARK,
SIDE_LIGHT
}

side s = SIDE_DARK;

C++11 引入了scoped enums(又名strong enums),它按照您的原始代码所需的方式工作。要获得完整的强大枚举,您必须使用 enum class 专门请求它:

enum class side {
DARK,
LIGHT,
}

side s = side::DARK;

但为了友好起见,C++11 允许您在使用枚举器名称时使用命名空间表示法,无论您使用的是强枚举还是传统枚举。这支持您的猜测,即您的同事在他的 Makefile 或编译器选项中打开了 C++11,(例如使用 -std=c++0x-std=c++11)。

MSVC(也许还有其他编译器)有一个非标准扩展,允许您像使用命名空间一样使用枚举,即使在较旧的 C++ 版本中也是如此,所以如果这是 gcc 和 MSVC 之间的区别,那是有道理的,但是您已经在问题中排除了这种可能性。 (我只为 future 的读者提及它。)

由于这是一个大型项目,您应该在您的编码标准或其他项目文档中设置您的目标语言版本。如果您的目标是 C++11,那么您需要更新项目的编译器选项,以便编译原始代码(因为它是有效的 C++11)。如果您的目标是 C++03,任何像您的第一个示例那样编写过代码的人都需要修复它,而不是依赖非标准选项或编译器扩展。

当然,如果您的目标是 C++11,并且不使用强枚举,您可以选择是否将枚举名称用作命名空间。您可能希望在您的编码标准中指定这一点,或者(更好的是)指定应尽可能使用强枚举。

关于c++ - 不一致的完全限定枚举编译时行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33756453/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com