陈浩南*_*陈浩南 8 c++ language-lawyer
前向声明的模板变量会导致 ld 错误。
#include <iostream>
template<class T> extern int a;
template<class T> int a = 1;
int main()
{
std::cout << a<int> << a<float>;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
$ LANG=C g++ main.cpp -o main
/usr/bin/ld: /tmp/cccOb25F.o: in function `main':
main.cpp:(.text+0x6): undefined reference to `a<int>'
/usr/bin/ld: main.cpp:(.text+0x1d): undefined reference to `a<float>'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
但是,前向声明变量(无模板)和前向声明模板函数工作正常。
#include <iostream>
extern int a;
int a = 1;
template<class T> int b();
template<class T> int b()
{
return 2;
}
int main()
{
std::cout << a << b<int>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
那么,是否可以使 C++ 中的前向声明模板变量起作用?
编辑:
由于clang++
工作正常,也许我不小心发现了一个错误g++
?
编辑2:
我发现了大约 2.5 年前的错误报告(这里),这是完全相同的问题。哦,我们需要一个可以阅读 gcc 源代码并修复它的人......
这是GCC 错误 83342,尚未解决。
无论有意与否,GCC 似乎假设首先extern
在给定翻译单元 (TU) 中使用关键字声明的变量模板必须在另一个TU 中定义(因此甚至不在同一个 TU 中查找它)。例如,Clang 没有做出这个假设(并且在同一个 TU 中找到了定义和重新声明)。
template<class T> extern int a; // extern declaration.
template<class T> int a = 1; // definition.
template int a<int>; // explicit instantiation definition for a<int> specialization.
// Clang: OK
// GCC:
// - error: explicit instantiation of 'a<int>' but no definition available
int main() {}
Run Code Online (Sandbox Code Playgroud)
标准中没有条款允许 GCC 做出上述假设,并且公开的错误报告是有效的。
我们可能会注意到 GCC 接受函数模板的类似且可能更常见的情况:
template<class T> extern void f(); // extern declaration.
template<class T> void f() {} // definition.
template void f<int>(); // explicit instantiation definition for f<int>() specialization.
// Clang: OK
// GCC: OK
int main() {}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
167 次 |
最近记录: |