我收到错误消息,说明编译器在以下代码中尝试将std::pair<const K, V>
的复制构造函数与std::map
一起使用
#include <iostream>
#include <map>
#include <tuple>
using std::cout;
using std::endl;
class Something {
public:
Something(const Something&) = delete;
Something(Something&&) {
cout << __PRETTY_FUNCTION__ << endl;
}
Something() = default;
};
int main() {
auto map = std::map<int, Something>{};
map.insert({1, Something{}});
}
错误在这里https://wandbox.org/permlink/OeyxtMjLy6HvJI5L(转载如下)
note: 'std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = Something]' is implicitly deleted because the default definition would be ill-formed:
constexpr pair(const pair&) = default;
^~~~
这很奇怪,因为新的C ++ 17规则将insert的重载更改为接受const value_type&
和value_type&&
,而不是之前的模板转发参考版本insert
({{ 3}})。哪些禁止使用列表初始化等(好奇为什么他们没有为其他insert
重载提供默认模板参数,这可能有类似的行为,但这是另一个问题)
应选择value_type
的左值版本。那么为什么选择对复制构造函数呢? libstdc ++代码中的这个注释是否与http://en.cppreference.com/w/cpp/container/map/insert的任何内容有关?
此错误不会出现在clang(https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_map.h#L805)上。不确定这是否是wandbox上的标准库问题或编译器问题。如果这是一个编译器问题那么谁是对的?