我有一些非常简单的 ( C++11 ) 代码,最新的clang (版本 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 发出以下错误:
错误:非类型模板参数引用了没有链接的函数“foo”
但是,如果我将类型移动Bar
到全局范围(通过将其从函数中取出),那么 clang 可以很好地编译它,证明问题在于类型为function-local。
那么发出这个错误的clang是正确的,还是标准不支持这个(在这种情况下,GCC允许它太宽松了)?
编辑#1:需要明确的是,这不是这个问题的重复,因为在 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;
}