下面的代码没有链接到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::vector、std::deque或std::set替换std::queue,或者我删除了显式的模板实例化,它就会起作用。
如果我用调用q = std::queue<int>{}的完整构造函数替换q = {},它也可以工作。
这段代码是不标准的,还是编译器/libc++的bug?
发布于 2020-08-26 04:22:16
我不确定为什么你会得到这样的链接器错误,也许是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.queue不允许使用initializer_list进行列表初始化,这里有这样的说明:Why can't I construct a queue/stack with brace-enclosed initializer lists? (C++11)
但是,如果您使用libc++ (-stdlib=libc++):https://coliru.stacked-crooked.com/a/df9d859a239843cf,您似乎可以编译您的代码(至少在coliru上,我在godbolt上尝试过,但没有成功)。
它可能没有给出你的问题的确切答案,但我认为它太长了,不能发表评论。你也可以在这里找到类似的线索:https://github.com/envoyproxy/envoy/issues/9106
编辑有趣,在重置godbolt并使用相同的配置(https://godbolt.org/z/TzE9h9)再次输入代码后,一切工作正常。
https://stackoverflow.com/questions/63582130
复制相似问题