首页 > 解决方案 > 本地类的限定名称

问题描述

typename声明中的关键字在其后需要一个限定的类型名称(一个在其前面带有嵌套名称分隔符的类型名称)。但是本地类或结构的限定名称是什么?这是示例:

struct A{};
namespace bb { struct B{}; }
int main()
{
    struct C{};

    typename A a; // not OK, because A is not a qualified typename
    typename ::A a; // OK, because it contains a nested name specifier
    typename B b; // not OK, because B is not a qualified typename
    typename bb::B b; // OK, because it contains a nested name specifier
    typename C c; // not OK in gcc and clang but compiles in Visual Studio
}

这是我从 clang 得到的错误:expected a qualified name after 'typename'

这是 gcc 报告的错误:<source>:21:14: error: expected nested-name-specifier before 'C'

之后可以使用本地类名typename吗?如果是这样,那么它的限定名称是什么?该类main()::C在 clang 错误消息中报告,但这显然不是它的限定名称。我在 C++ 标准中找不到禁止在这种情况下使用本地类的地方。我错过了什么吗?Visual Studio 没有抱怨,typename C c;所以它是 gcc 和 clang 中的错误吗?

PS。我知道如果我不使用模板,我可以在变量前面声明没有 typename 的变量,但我只是好奇这是语言中的错误、gcc/clang 或 Visual Studio 中的错误,还是我遗漏了一些东西。

标签: c++c++11language-lawyer

解决方案


听起来 gcc 和 clang 更严格和正确,而 VS 更宽松(不确定它是否属于错误)。

正如您已经正确编写的那样,typename需要一个限定名称。那是“出现在范围解析运算符右侧的名称::”。无法::与本地类一起使用,这意味着没有::- 限定名称(因此,如上面引用的定义)。这样的要求是否具有良好的逻辑,后人可能会决定,但对于价值,以下确实有效:

int main()
{
    struct C { public: struct D{}; };

    typename C::D d; // ok

    return 0;
}

同样值得一提的是,如果使用较旧的编译器,typename则允许在模板之外使用以 开头。c++11


推荐阅读