【问题标题】:clang error "explicit instantiation does not refer to a function template" across multiple namespaces跨多个命名空间的clang错误“显式实例化不引用函数模板”
【发布时间】:2021-01-18 06:35:52
【问题描述】:

我正在尝试在我自己的命名空间中重用现有的模板化函数,并出于代码覆盖的原因显式实例化它们。

以下代码使用 gcc 9.3 编译,但使用 clang 10.0.0 编译

namespace bar {
    template<typename T>
    T func(T arg){ return arg;};
}

namespace foo {
    using bar::func;
}

template int foo::func<int>(int);

int main()
{ }

查看示例here

如果我将模板函数实例化为

template int bar::func<int>(int);

clang 也可以编译。但这不是我想要的。

是否可以使用 clang 跨命名空间显式实例化模板函数?

为什么 gcc 和 clang 给出不同的结果?

【问题讨论】:

    标签: c++ templates gcc namespaces clang


    【解决方案1】:

    恐怕你不能那样做。 Clang 是正确的。

    [temp.explicit]

    2 显式实例化的语法是:

    显式实例化:
        externopt 模板声明

    4 如果显式实例化是针对类或成员类, 声明中的详细类型说明符应包括 简单模板 ID;否则,声明应为 简单声明,其 init-declarator-list 包含单个 没有初始化器的 init-declarator。

    本段告诉我们,template 关键字后面的位必须在语法和语义上都是对某事的有效声明(并且不得包含初始化程序,这与此处无关)。一个声明有几个部分,但这里感兴趣的是声明的 declarator 部分。

    关于我们有以下一段

    [dcl.meaning](强调我的)

    1 一个声明符只包含一个声明符id;它命名 声明的标识符。一个不合格的 id 发生在 declarator-id 应该是一个简单的标识符,除了声明 一些特殊函数([class.ctor]、[class.conv]、[class.dtor]、 [over.oper]) 和模板特化的声明或 部分专业化([temp.spec])。 当 declarator-id 是 限定,声明应引用先前声明的成员 限定符所指的类或命名空间(或者,在 命名空间的情况,它的内联命名空间集合的元素 namespace ([namespace.def])) 或其专业化; 的 成员不应仅由 using 声明引入 指定的类或命名空间的范围 声明符 id 的嵌套名称说明符

    由于您在显式模板实例化中的 declarator-id 是 foo::func,因此它不遵循我用粗体标记的句子中列出的规则。这使您对显式实例化的尝试格式错误。

    GCC 也应该拒绝你的尝试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-15
      • 1970-01-01
      • 2021-12-29
      • 2013-08-31
      • 1970-01-01
      相关资源
      最近更新 更多