代码之家  ›  专栏  ›  技术社区  ›  xmh0511

clang中定义名称空间的成员而不使用嵌套的名称说明符是一个bug吗

  •  0
  • xmh0511  · 技术社区  · 4 年前
    namespace A{
        namespace B{
            template<typename T>
            struct Test{
            };
        }
        using namespace B;
        template<>
        struct Test<int>{};  //#1
    }
    
    int main(){
    
    }
    

    考虑上面的代码, GCC 抱怨此类代码格式错误且 Clang 认为这样的代码是良好的形成。结果是 here #1 ,它是类模板的显式专门化声明 Test .根据这条规则:
    temp.expl.spec#2

    显式专门化可以在 可以定义相应的主模板 .

    主模板 测验 可以在命名空间之外定义 B ,只要它遵守以下规则:
    namespace.memdef#2

    命名名称空间的成员也可以在该名称空间之外定义 通过定义名称的显式限定([namespace.qual]) ,前提是要定义的实体已在命名空间和定义中声明 出现在包含声明命名空间的命名空间中的声明点之后 .

    也就是说,我们可以定义主模板 测验 这样地:

    namespace A{
        namespace B{
            template<typename T>
            struct Test;
        }
        template<typename T>
        struct B::Test{  // Test is explicit qualified by B
        }; 
    }
    

    所以,我们可以在这个点上定义明确的专门化。然而,目前尚不清楚是否有必要通过使用限定id来声明这种明确的专门化?不过,这里还有一条规则:
    temp.expl.spec#8

    模板显式专门化是 在定义模板的命名空间的范围内 .

    所以 叮当声 怎么了?如何解释这种情况。

    0 回复  |  直到 4 年前
        1
  •  4
  •   Davis Herring    4 年前

    你是对的,现有的措辞有点不清楚。如果它有一个含义,我不会试图去理解它的书面含义,比你已经理解的更深;我认为需要一个 complete rewrite .

    这个 意图 然而,这个代码是格式良好的(正如Clang所说);因为(类模板的)显式专门化必须包含 Test< ,这可能是 嵌套名称说明符 ( template<> struct Test<int>::Nested<float> {}; ), Test 要遵循 使用指令 (在许多其他事情中)。请注意,这与[class.pre]/3不同,后者禁止使用 嵌套名称说明符 重新申报通过 使用声明 (函数模板的显式专门化和实例化规则要复杂一些,因为模板参数列表是可选的。)

    几周内,我的链接论文将公开更新,按照这些思路调整重新声明的规则(在本例中为[class.pre])。