mfo*_*ini 12 c++ movable noncopyable c++11
看看下面的代码:
#include <utility>
#include <map>
// non-copyable but movable
struct non_copyable {
non_copyable() = default;
non_copyable(non_copyable&&) = default;
non_copyable& operator=(non_copyable&&) = default;
// you shall not copy
non_copyable(const non_copyable&) = delete;
non_copyable& operator=(const non_copyable&) = delete;
};
int main() {
std::map<int, non_copyable> map;
//map.insert({ 1, non_copyable() }); < FAILS
map.insert(std::make_pair(1, non_copyable()));
// ^ same and works
}
Run Code Online (Sandbox Code Playgroud)
在取消注释g ++ 4.7上的标记行时,编译此代码段失败.产生的错误表明non_copyable
无法复制,但我预计它会被移动.
为什么插入std::pair
使用统一初始化的构造失败但没有使用构造std::make_pair
?两者都不应该产生可以成功移入地图的右值吗?
Ker*_* SB 18
[这是完全重写.我之前的回答与这个问题无关.]
将map
有两个相关的insert
重载:
insert(const value_type& value)
,和
<template typename P> insert(P&& value)
.
使用简单列表初始化程序时map.insert({1, non_copyable()});
,会考虑所有可能的重载.但只发现了第一个(一个采取const value_type&
),因为另一个没有意义(没有办法神奇地猜测你打算创建一对).第一个重载当然不起作用,因为您的元素不可复制.
您可以通过显式创建对来使第二个重载工作make_pair
,如您所述,或者通过显式命名值类型:
typedef std::map<int, non_copyable> map_type;
map_type m;
m.insert(map_type::value_type({1, non_copyable()}));
Run Code Online (Sandbox Code Playgroud)
现在list-initializer知道查找map_type::value_type
构造函数,找到相关的可移动函数,结果是一个rvalue对,它绑定到函数的P&&
-overload insert
.
(另一种选择是使用emplace()
与piecewise_construct
和forward_as_tuple
,虽然会得到很多更详细.)
我认为这里的道德是list-initializers寻找可行的重载 - 但他们必须知道要寻找什么!
归档时间: |
|
查看次数: |
4386 次 |
最近记录: |