使用Clang 10使用显式模板实例化〜queue的未定义引用

问题描述

以下代码链接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;
}

我从编译器得到的是:

Online example

/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::vectorstd::dequestd::set,它将起作用;或删除显式模板实例化。

如果我将q = {}替换为完整的构造函数调用q = std::queue<int>{},它也将起作用。

代码不是标准代码,还是编译器/ libc ++错误

解决方法

我不确定为什么会出现此类链接器错误,也许是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)输入代码后,一切正常。