C++ C++;对于哪些类型,参数类型名称可以与带有类型说明符的参数名称相同?

C++ C++;对于哪些类型,参数类型名称可以与带有类型说明符的参数名称相同?,c++,parameters,enums,specifier,C++,Parameters,Enums,Specifier,对不起,这个问题需要解释一下。我正在修复DyxGEN解析一些C++代码,我遇到了一个不寻常的角情况,DoXEGEN不解释。我有一个补丁,但我想让它更一般,所以我需要一些解释 为了说明doxygen失败的情况,我将定义一个涉及辛普森一家的人为例子(因为这类问题似乎很流行)。假设我们有以下枚举: enum simpson { HOMER, MARGE, BART, LISA, MAGGIE }; 现在,我们希望将枚举值传递到(Simpsons类的)方法中,该方法如下所示: const char*

对不起,这个问题需要解释一下。我正在修复DyxGEN解析一些C++代码,我遇到了一个不寻常的角情况,DoXEGEN不解释。我有一个补丁,但我想让它更一般,所以我需要一些解释

为了说明doxygen失败的情况,我将定义一个涉及辛普森一家的人为例子(因为这类问题似乎很流行)。假设我们有以下枚举:

enum simpson { HOMER, MARGE, BART, LISA, MAGGIE };
现在,我们希望将枚举值传递到(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*";
    }
}
const char* voicedBy(enum simpson simpson)
不幸的是,这会产生一个编译器错误,因为枚举类型“simpson”不允许与参数名“simpson”相同(与C#不同)。但是,C++对此有答案。将enum关键字放在类型名称前面,如下所示:

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*";
    }
}
const char* voicedBy(enum simpson simpson)
代码现在将编译并运行。不幸的是,doxygen没有考虑这种情况,因此它将整个字符串“enum simpson simpson”视为没有参数名称的参数类型。我已经想出了一些代码来修复上述枚举中的doxygen


我的问题是,这种把戏还适用于其他什么类型?结构、联合、类型定义、其他?就这一点而言,“与参数名同名的方法参数的类型说明符”概念是否有一个名称,以便我可以获得有关它的更多详细信息?

struct
/
class
/
union
。本标准中,“详细的类型说明符”,由“类密钥标识符”组成,见3.4.4-1。(顺便说一句,如果
开关
大小写
返回
s,则无需
中断

在C中,结构、
联合
枚举
的规范名称包括该前缀:

struct Point {
    int x, y;
};

enum Type {
    FIRST, SECOND, THIRD
};

struct Point p;
enum Type t;
这就是创建前缀已删除的
typedef
名称的习惯用法的来源:

typedef struct Point {
    int x, y;
} Point;

typedef enum Type {
    FIRST, SECOND, THIRD
} Type;

struct Point p;
enum Type t;
Point p;
Type t;
C++也有这一点,同样的行为也适用于
class
,类似的行为适用于模板中的
template
typename
。但是,它也删除了包含前缀的要求,除非在不明确的情况下


我认为这个概念没有名字,但我得到了纠正:它是一个精心设计的类型说明符。一个合适的解决方法可能是将Doxygen注释放在声明上,而不是定义上。

您在声明中所做的与C代码编写人员整天所做的相同的事情—在用户定义的类型前面加上适当的关键字。这同样适用于结构、类、联合、typedef、变量声明,基本上适用于任何地方。

您使用的编译器和版本是什么

void foo( simpson simpson ) {}
不存在
enum
present,也就是说,您不需要在此上下文中使用精心设计的类型说明符,它在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!
}
如果使用与所需类型相同的名称定义函数,则可能会发生相同类型的名称隐藏:

void simpson();
void voicedBy( enum simpson s );
//             ^^^^ required
请注意,如果添加一个typedef,在最后一种情况下,情况会发生一些变化:typedef名称和函数名称(或同一范围内的变量名称)之间会出现名称冲突


*此处隐藏的含义不是一个作用域中的变量在一个外部作用域中隐藏具有相同名称的变量。在C++中,和C一样,有两个标识符空间,一个用于用户定义类型,另一个用于大多数其它的,包括<代码> TyPulf< /COD> -ED类型别名。从内部范围到外部范围执行C++中的查找,并且在每个范围内搜索全局标识符空间,如果未找到标识符,则搜索用户定义的类型标识符空间以获得相同的标识符。最后一步不是在C中执行的,因为C中始终需要详细的类型说明符。只有在同样失败的情况下,编译器才会移动到下一个作用域。

Nice(好吧……在“我不知道那个”的意义上是Nice,但不是Nice)技巧。请原谅,我要找到编写代码的人并当面攻击他们:p.什么编译器和版本?上述代码示例应在编译时不需要任何详细的类型说明符。@DavidRodríguez dribeas gcc 2.95.3。A/gcc的旧版本。你说得对,在现代C++编译器中,这种技巧是不必要的,但是原始代码不是用现代编译器编写的。我知道我会在我的示例代码中拧一些东西,因为我没有编译它。即使这样,也不会捕获它,因为它将编译并工作得很好。。。只是那些
break
行在执行过程中永远无法到达-无论如何都应该被优化者删除,但是没有它,代码会读得更好。你的答案很好。Tony得到了公认的答案,只是因为他知道这被称为“精心设计的类型说明符”。gcc 2.95.3。最终测试了这一点,并且您是正确的,在C++代码中,参数参数不需要枚举部分,但需要声明该类型的局部变量。我没有检查常规函数的参数是否需要enum,因为我没有使用它们。