问题描述
以下代码不链接Clang 10,但可以成功使用GCC和Clang 9:
#include <queue>
template <typename T>
class A
{
public:
void f();
private:
std::queue<int> q;
};
template <typename T>
void A<T>::f()
{
q = {};
}
template class A<int>;
int main()
{
return 0;
}
我从编译器得到的是:
/opt/compiler-explorer/gcc-9.3.0/lib/gcc/x86_64-linux-gnu/9.3.0/../../../../x86_64-linux-gnu/bin/ld: /tmp/example-f70f65.o: in function `A<int>::f()':
/home/ce/<source>:16: undefined reference to `std::queue<int,std::deque<int,std::allocator<int> > >::~queue()'
clang-10: error: linker command Failed with exit code 1 (use -v to see invocation)
Compiler returned: 1
如果我将std::queue
替换为std::vector
,std::deque
或std::set
,它将起作用;或删除显式模板实例化。
如果我将q = {}
替换为完整的构造函数调用q = std::queue<int>{}
,它也将起作用。
解决方法
我不确定为什么会出现此类链接器错误,也许是Godbolt的某些独特问题。如果您尝试使用coliru:https://coliru.stacked-crooked.com/a/ac9c188334f858d8来编译代码,则会收到一个编译时间错误,表明您尝试使用队列的列表初始化:
launch.json
队列不允许使用initializer_list进行列表初始化,此处是Why can't I construct a queue/stack with brace-enclosed initializer lists? (C++11)
但是,如果您使用libc ++(-stdlib = libc ++),似乎可以编译代码(至少在coliru上,我尝试过Godbolt没成功):https://coliru.stacked-crooked.com/a/df9d859a239843cf
它可能无法给出您问题的确切答案,但是我来不及发表评论了。另外,您可能会在这里找到类似的线程:https://github.com/envoyproxy/envoy/issues/9106
[编辑] 有趣的是,在重置Godbolt UI并再次使用相同配置(https://godbolt.org/z/TzE9h9)输入代码后,一切正常。