【发布时间】:2013-09-01 04:18:09
【问题描述】:
我有一些非常简单的 (C++11) 代码,最新的 clang (version 3.4 trunk 187493) 无法编译,但 GCC 编译得很好。
代码(如下)使用函数本地类型 Bar 实例化函数模板foo,然后尝试将其地址用作类的非类型模板参数-模板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 发出以下错误:
错误:非类型模板参数指的是函数 'foo' 没有链接
但是,如果我将类型 Bar 移动到全局范围(通过将其从函数中取出),那么 clang 可以很好地编译它,证明问题在于类型为 function-local。
那么发出这个错误的 clang 是正确的,还是标准不支持这个(在这种情况下 GCC 允许它太宽松了)?
编辑 #1: 需要明确的是,这不是与 this question 的重复,因为 “不能使用本地类型作为模板参数” 限制在 C++11 中被删除。 然而,目前还不清楚使用本地类型是否存在链接影响,以及发出此错误时 clang 是否正确。
EDIT #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;
}
【问题讨论】:
-
最新版本的 Xcode 附带的 clang 表示“错误:非模板参数指的是具有内部链接的函数 'foo
'”。跨度> -
@jxh,即使将
--std=c++11传递给 clang,也会发生这种情况。 -
@jxh:这不是那个问题的重复,因为 C++11 删除了该限制,并且 clang 声称这是某种链接错误。
-
@etherice: 没关系
inline- 我不知道是否可以使用没有链接的类型实例化foo模板并获得具有链接的东西... -
如果 14/4 能谈谈模板特化的链接,那就太好了。它似乎在回避这个问题。
标签: c++ templates gcc c++11 clang