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

PJK*_*136 5 c++ templates c++11 clang++

以下代码未链接 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;
}
Run Code Online (Sandbox Code Playgroud)

我从编译器得到的是:

在线示例

/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
Run Code Online (Sandbox Code Playgroud)

如果我替换std::queuestd::vector,std::dequestd::set; 或者如果我删除显式模板实例化。

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

这段代码是不标准的还是编译器/libc++ 错误?

mar*_*inj 0

我不确定为什么会出现这样的链接器错误,也许是 godbolt 的一些独特问题。如果您尝试使用 coliru 编译代码:https://coliru.stacked-crooked.com/a/ac9c188334f858d8,您将收到编译时错误,表明您尝试使用队列的列表初始化:

main.cpp:16:7: error: no viable overloaded '='
    q = {};
    ~ ^ ~~
main.cpp:19:16: note: in instantiation of member function 'A<int>::f' requested here
template class A<int>;
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../../include/c++/5.5.0/bits/stl_queue.h:96:11: note: candidate function (the implicit move assignment operator) not viable: cannot convert initializer list argument to 'std::queue<int, std::deque<int, std::allocator<int> > >'
    class queue
          ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../../include/c++/5.5.0/bits/stl_queue.h:96:11: note: candidate function (the implicit copy assignment operator) not viable: cannot convert initializer list argument to 'const std::queue<int, std::deque<int, std::allocator<int> > >'
1 error generated.
Run Code Online (Sandbox Code Playgroud)

队列不允许使用initializer_list进行列表初始化,这里有这样的内容:Why can't I Construction a queue/stack with括号括起来的初始值设定项列表?(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)后,一切正常。