首页 > 解决方案 > C++ 模板特化中的声明范围

问题描述

对于以下代码:

namespace A
{
    struct B
    {
        using type = std::tuple<struct C>;
    };
}

int main()
{
    C* ptr = nullptr;
    B::C* ptr2 = nullptr;
    A::B::C* ptr3 = nullptr;
    A::C* ptr4 = nullptr;
}

我只想知道范围是什么C。我在 gcc 6.5/7.4/8.3/9.1 和 clang 6/7/8 中尝试过,他们都告诉我这A::C是正确的。但我不确定 C++ 标准中是否有任何材料描述了C上述情况的范围。

您能否告诉我您是否知道与该主题相关的 C++ 标准中的资料?非常感谢 !

标签: c++templateslanguage-lawyer

解决方案


这在 C++ 标准的以下部分中有详细说明:

[基本.lookup.elab]

2如果详细类型说明符由类键引入,并且此查找未找到先前声明的类型名称,或者详细说明类型说明符出现在具有以下形式的声明中:

   类键属性说明符序列选择标识符;

详细类型说明符是一个声明,它引入了 [basic.scope.pdecl] 中描述的类名。

[basic.scope.pdecl](强调我的)

7在详细类型说明符中首先声明的类的声明点如下:

  • [...]
  • ...如果在命名空间范围内定义的函数的 decl-specifier-seq 或参数声明子句中使用了详细类型说明符,则标识符在包含该声明的命名空间中声明为类名;否则,除非作为友元声明,否则标识符将在包含该声明的最小命名空间或块范围内声明。

模板的参数列表属于“否则”子句。A是包含声明的最小命名空间,因此类类型C在其中声明。A::C是引用它的正确方法。


推荐阅读