gpt4 book ai didi

c++ - 铿锵错误 : non-type template argument refers to function that does not have linkage -- bug?

转载 作者:可可西里 更新时间:2023-11-01 16:39:33 24 4
gpt4 key购买 nike

我有一些非常简单的 (C++11) 代码,最新的 clang(version 3.4 trunk 187493)无法编译,但 GCC 编译正常。

代码(下面)实例化函数模板 foo使用局部函数类型 Bar然后尝试将其地址用作类模板 Func 的非类型模板参数:

template<void(*FUNC_PTR)(void)>
struct Func {};

template<typename T> extern inline
void foo() {
using Foo = Func<foo<T>>;
}
int main() {
struct Bar {}; // function-local type
foo<Bar>();
return 0;
}

clang 发出以下错误:

error: non-type template argument refers to function 'foo' that does not have linkage

但是,如果我移动类型 Bar到全局范围(通过将其从函数中取出),然后 clang 可以很好地编译它,证明问题出在 function-local 类型上。

那么 clang 发出这个错误是正确的,还是标准不支持这个(在这种情况下,GCC 允许它过于宽松)?


编辑 #1 :要清楚,这 不是 this question 的拷贝因为 “不能使用本地类型作为模板参数” 限制在 C++11 中被移除了。 但是,目前还不清楚使用本地类型是否涉及链接含义,以及 clang 在发出此错误时是否正确。


编辑 #2: 已确定 clang 发出上述代码的错误是正确的(请参阅@jxh 的回答),但它 不正确也会发出错误对于以下代码(将 using 声明从 foo<Bar>() 范围移至 main() 范围):

template<void(*FUNC_PTR)(void)>
struct Func {};

template<typename T> extern inline
void foo() {}

int main() {
struct Bar {};
using F = Func<foo<Bar>>;
return 0;
}

最佳答案

根据 C++.11 §3.5 程序和链接 ¶2 中无链接 的定义,我最初相信 foo<Bar>没有链接,因为除了定义类型 Bar 的范围外,任何其他范围都不能通过名称引用它(即 main() )。然而,这是不正确的。这是因为具有外部链接的名称的定义被描述为:

When a name has external linkage, the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.

对于模板函数,情况总是如此。这是因为可以从另一个范围引用该名称。即,模板函数可以引用自身。因此,foo<Bar>有外部链接。 zneak's answer, EDIT 2 , 有一封电子邮件线程与 clang 开发人员确认 foo<Bar>应该有外部链接。

因此,从 C++.11 §14.3.2 模板非类型参数 ¶1:

A template-argument for a non-type, non-template template-parameter shall be one of: ...

  • a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as &id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; ...

  • 最相关的项目符号是第三个项目符号。自 foo<bar>具有外部链接,将其作为非类型模板参数传递应该没问题。

    关于c++ - 铿锵错误 : non-type template argument refers to function that does not have linkage -- bug?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18498957/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com