【发布时间】:2020-09-16 09:53:39
【问题描述】:
我有一段 C++ 代码,我不确定它是否正确。考虑以下代码。
#include <memory>
#include <vector>
#include <map>
using namespace std;
int main(int argc, char* argv[])
{
vector<map<int, unique_ptr<int>>> v;
v.resize(5);
return EXIT_SUCCESS;
}
GCC 编译这段代码没有问题。然而,英特尔编译器(版本 19)因错误而停止:
/usr/local/ [...] /include/c++/7.3.0/ext/new_allocator.h(136): error: function "std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2> &) [with _T1=const int, _T2=std::unique_ptr<int, std::default_delete<int>>]" (declared at line 292 of "/usr/local/ [...] /include/c++/7.3.0/bits/stl_pair.h") cannot be referenced -- it is a deleted function
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^
detected during:
[...]
instantiation of "void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type={std::size_t={unsigned long}}) [with _Tp=std::map<int, std::unique_ptr<int, std::default_delete<int>>, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, std::default_delete<int>>>>>, _Alloc=std::allocator<std::map<int, std::unique_ptr<int, std::default_delete<int>>, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, std::default_delete<int>>>>>>]"
at line 10 of "program.cpp"
两个编译器都可以毫无问题地编译以下代码。
#include <memory>
#include <vector>
#include <map>
using namespace std;
int main(int argc, char* argv[])
{
vector<unique_ptr<int>> v;
v.resize(5);
return EXIT_SUCCESS;
}
第一个代码在英特尔编译器上失败,因为它试图创建一个 unique_ptr 的副本,它只定义了一个移动构造函数。但是,我不确定第一个程序是否是合法的 C++ 程序。
我想知道第一个代码是否错误或英特尔编译器是否存在错误。如果第一个代码是错误的,为什么第二个代码是正确的?还是第二个也错了?
【问题讨论】:
-
在我看来像一个英特尔漏洞。
-
英特尔很可能没有将
pair的移动构造函数标记为noexcept。如果这是一个 QOI 问题或实际上是一个错误,我可以回忆一下。 -
@NathanOliver 英特尔使用 GCC 的 STL(它没有),所以它会使用 GCC 可用的任何东西
-
@SergeyA 但
noexcept和std::is_nothrow_move_constructible需要编译器支持,而且它们似乎无法在 ICC 上映射唯一指针 -
MSVC 18.00.40629(从2017年15.9.2开始)也有这个问题