- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我和一位同事在使用枚举时遇到了一个奇怪的行为。
我们都在使用(大概)相同的 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/
我想创建一个基于 jQuery 的非常简单的 html 编辑器(不是所见即所得)。 我的问题是如何制作 textarea或 div可能 在上面写一些文字 然后样式即标签(例如 some stuff 将
根据文档 isset 条款“测试此项目中是否已设置给定属性”。我不明白设置属性时 isset 返回 true 还是 false 在下面的代码片段中,当 env.JAVA_HOME 未设置时,java.
我正在尝试取消映射 o这是执行 :only 的默认命令( :help :only ),所以我尝试的第一件事是: nmap o 这种作品,除非我按 ,等待超过timeoutlen ms 然后按 o
我有以下型号: class MetaData(models.Model): created_at = models.DateTimeField(auto_now_add=True, auto_
下面列出了两行代码。两者对日期和时间的期望相同,但只有一个有效。我正在使用 R 3.1。 以下不起作用: DateTime2=strftime("08/13/2010 05:26:24.350", f
我有一个关于 C 代码的问题。 #include void foo(void){ int a; printf("%d\n",a); } void bar(void){
如果文件大小 > 8k,为什么读取的最后一个字节 = 0? private static final int GAP_SIZE = 8 * 1024; public static void main(
我有一个命令 Get-Testdata从不同来源检索测试数据并将这些数据存储到 PSObject以不同的值作为属性。然后将对象总数存储为数组,以便于操作、排序、计算等。 我的问题是我希望能够将这些数据
我正在使用 epoll 将大消息写入使用 HTTP 协议(protocol)的服务器。 fds 都设置为非阻塞,我正在使用边缘触发事件。我知道对于 EPOLLIN,我需要循环读取 fd,直到返回 EA
这对我来说听起来很奇怪: $test_1 = 'string'; $test_2 = '0'; var_dump(intval($test_1)); // Output: int 0 var_dump
这个问题在这里已经有了答案: Java: Integer equals vs. == (7 个回答) 7年前关闭。 请您解释以下行为。 public class EqAndRef { publ
Drupal 的行为到底是什么? 它为模块开发人员提供什么类型的服务层? 它映射到 jQuery.ready 的关系类型是什么? 最佳答案 长版:Drupal.behaviors 不仅仅是 jQuer
以下代码: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ for (int i=0
人们可以将项目添加到数据库中。我让他们选择在此时添加它,或手动选择日期。 因此我得到了这个 HTML 结构。 (请注意,我将日期和时间选择器妥协为只有一行文本) Selec
创建了一个数据框: simpleDF is.na(simpleDF$vals) [1] TRUE TRUE FALSE > is.nan(simpleDF$vals) [1] FALSE TRU
我有一个大的 docker 镜像 A,我创建了一个新的 Dockerfile FROM A RUN rm /big-folder 我尝试使用以下方法构建图像: docker build --squas
我想知道以下情况下 JVM 的行为是什么: JVM 最小堆大小 = 500MB JVM 最大堆大小 = 2GB 操作系统有 1GB 内存 JVM启动后,程序运行一段时间后,使用内存超过1GB。我想知道
我们正在使用 spikeearrest 策略,但我们不了解其工作原理。峰值逮捕配置如下: 5pm 阅读文档,我们了解到,如果我们在一分钟内调用此流超过 5 次,则该策略将在第 5 次之后
我正在使用 cURL 发送 POST 请求: curl http://tarvos.local:8080/partial_Users/2 -d '{currentPage : 1, firstID :
我的表中有 6442670 条记录,我正在使用以下命令获取它们jdbctemplate 使用行号一次 1000000 个。以下是查询 select * from (select rowNum rn
我是一名优秀的程序员,十分优秀!