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

标签 c++ parameters enums specifier

抱歉,这个问题需要解释一下。我正在修复 doxygen 解析一些 C++ 代码时的疏忽,我遇到了一个 doxygen 没有考虑的不寻常的极端情况。我有一个修复程序,但我想让它更通用,所以我需要一些解释。

为了说明 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*";
    }
}

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

const char* voicedBy(enum simpson simpson)

现在代码将编译并运行。不幸的是,doxygen 没有考虑这种情况,因此它将整个字符串“enum simpson simpson”视为没有参数名称的参数类型。我想出了一些代码来修复像上面这样的枚举的 doxygen。

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

最佳答案

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

void foo( simpson simpson ) {}

不存在 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!
}

如果您定义一个与您想要的类型具有相同名称的函数,则可能会发生相同类型的名称​​隐藏:

void simpson();
void voicedBy( enum simpson s );
//             ^^^^ required

请注意,如果您添加 typedef,最后一种情况会发生一些变化:typedef 名称和函数名称(或同一作用域中的变量名称)之间会发生名称冲突。

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

关于C++ 对于哪些类型,参数类型名称可以与带类型说明符的参数名称相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6092220/

相关文章:

Java Applet 初始化方法

Python将函数参数转为字符串

SwiftUI - 使用枚举不更新查看

android - 如何在 Android 上将 Enum 读写到 parcel 中?

c++ - 使用assimp加载mtl颜色

c++ - QT_NO_DEBUG 是否会导致 NDEBUG 的定义?

python - 如何使用 pgdb.executemany?

android - 如何在 Retrofit 中使用 Kotlin 枚举?

c++ - 更改原始 vector 不会在集合中更改它

c++ - 执行超时(12000毫秒):是否有更好的方法来解决此问题?