我正在通过将typedef转换为使用别名来将某些C ++代码更新为C + 11的工作。鉴于以下SCCE:
#include <iostream>
#include <linux/cn_proc.h>
/**
* Legacy C structure
*/
struct sample {
enum what {
FOO,
BAR
} what;
};
void tdef( ) {
typedef enum sample::what demo;
demo a = sample::FOO;
std::cout << a << std::endl;
}
void usingdemo( ) {
using demo = enum sample::what;
demo a = sample::BAR;
std::cout << a
<< std::endl;
}
int main() {
tdef();
usingdemo();
}
我正在使用using声明得到警告:
warning: declaration ‘enum sample::what’ does not declare anything
using demo = enum sample::what;
^
尽管代码可以编译并很好地执行。编译器是 g ++(Ubuntu 5.4.0-6ubuntu1〜16.04.10)5.4.0 20160609 错误是在编译器中还是在我体内?
感谢您的答复。关于对C结构的评论:
“ S”是SCCE小,所以我发布了最小的结构 演示问题。我正在使用的实际结构是“ struct proc_event”,来自 linux/cn_proc.h。
我只是将其包括在内而没有“ extern C” 一切正常。
答案 0 :(得分:5)
问题是您同时创建了类型sample::what
和成员sample::what
。编译器应该并且显然确实可以解决此问题,并且警告是良性的并且显然是错误的。
问题消失了:
struct sample {
enum what {
FOO,
BAR
} what_instance; // << Different identifier here
};
和:
using demo = sample::what;
在任何情况下,由于多种原因,具有相同名称的类型标识符和实例标识符都是一个坏主意。这会使人感到困惑,在这种情况下,编译器也会感到困惑。也许编译器试图告诉您一些信息;-)
答案 1 :(得分:4)
错误是否出在编译器上?
这是一个编译器错误。它似乎已经被报告过:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66159。当在using声明中使用详细的名称说明符时,问题再次出现。在这种情况下,您需要使用详细的名称说明符,以避免与具有相同名称的成员产生歧义。
解决方法:改用typedef
声明:
typedef enum sample::what demo;
答案 2 :(得分:-1)
您可以简单地将演示类型定义为int,因为枚举可以转换为临时int
void usingdemo( ) {
using demo = int;
...
}