C++什么类型的参数类型名称可以与带有类型说明符的参数名称相同?

Joh*_*one 5 c++ parameters enums specifier

抱歉,这个问题需要一些探索.我正在修复doxygen解析一些C++代码的疏忽,我遇到了一个不寻常的角落案例,doxygen没有考虑到.我有一个修复,但我想让它更一般,所以我需要一些解释.

为了说明doxygen失败的情况,我将定义一个涉及"辛普森一家"的人为例子(因为这对于这些类型的问题似乎很受欢迎).假设我们有以下枚举:

enum simpson { HOMER, MARGE, BART, LISA, MAGGIE };
Run Code Online (Sandbox Code Playgroud)

现在我们要将枚举值传递给一个方法(自然是Simpsons类),如下所示:

const char* voicedBy(simpson simpson)
{
    switch (simpson) {
        case HOMER:
            return "Dan Castellaneta";
        case MARGE:
            return "Julie Kavner";
        case BART:
            return "Nancy Cartwright";
        case LISA:
            return "Yeardley Smith";
        case MAGGIE:
            return "*suck* *suck*";
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这会产生编译器错误,因为不允许枚举类型'simpson'与参数名称'simpson'相同(与C#不同).但是,C++有一个答案.您将enum关键字放在类型名称前面,如下所示:

const char* voicedBy(enum simpson simpson)
Run Code Online (Sandbox Code Playgroud)

现在代码将编译并运行.不幸的是,doxygen没有考虑到这种情况,所以它将整个字符串"enum simpson simpson"视为没有参数名称的参数类型.我已经提出了一些代码来修复doxygen,就像上面的枚举一样.

我的问题是,这种技巧有哪些其他类型?struct?,union?,typedef?,其他?就此而言,与参数名称'概念同名的方法参数的'类型说明符'是否具有名称,以便我可以获得更多详细信息?

Dav*_*eas 3

您使用什么编译器和版本?

void foo( simpson simpson ) {}
Run Code Online (Sandbox Code Playgroud)

没有enum存在,也就是说,您不需要在这种情况下使用详细的类型说明符,并且它可以在 gcc 4.2 和 4.6 中完美编译。问题在于,在函数内部,参数名称隐藏了类型,如果您想在该范围声明具有该类型的新变量,您将需要详细的类型说明符,但在函数签名中,它是从左到右解析的,这意味着第一个simpson是枚举,当时没有冲突。第二个simpson引入了本地名称,从那里开始,simpson引用参数而不是类型。

void relationship( /*enum*/ simpson simpson, enum simpson other = HOMER );
//                   ^^^^ optional           ^^^^ required
{
   enum simpson yet_another = simpson;
// ^^^^ required              ^^^^^^^ first argument!
}
Run Code Online (Sandbox Code Playgroud)

如果您定义一个与所需类型同名的函数,则可能会发生相同类型的名称隐藏:

void simpson();
void voicedBy( enum simpson s );
//             ^^^^ required
Run Code Online (Sandbox Code Playgroud)

请注意,如果添加 typedef,最后一种情况会发生一些变化:typedef 名称和函数名称(或同一范围内的变量名称)之间会出现名称冲突。

*这里的hides并不是指一个作用域中的变量隐藏外部作用域中同名的变量。在 C++ 中,就像在 C 中一样,有两个标识符空间,一个用于用户定义的类型,另一个用于大多数其他内容,包括typedef-ed 类型别名。C++中的查找是从内部作用域到外部作用域进行的,在每个作用域中搜索全局标识符空间,如果没有找到标识符,则在用户定义类型标识符空间中搜索相同的标识符。最后一步在 C 中不执行,因为 C 中始终需要详细的类型说明符。仅当这也失败时,编译器才会移至下一个作用域。