在地图中就地构建不可移动的对象
Construct-in-place an unmoveable object in a map
我正在尝试在包含原子的映射中构造一个对象,因此它既不能复制也不能移动 AFAICT。
我对 C++ reference 的阅读是 map emplace
应该能够做到这一点。但是由于删除或不存在的构造函数,以下代码无法编译。使用 make_pair
没有帮助。
#include <atomic>
#include <unordered_map>
class Z {
std::atomic<int> i;
};
std::unordered_map<int, Z> map;
void test(void) {
map.emplace(0, Z()); // error
map[0] = Z(); // error
}
这可能吗,如果不可能,为什么不呢?
编辑:编译器是 Linux
上的 gcc 4.8.1
map.emplace(std::piecewise_construct, std::make_tuple(0), std::make_tuple())
将在位置 0
.
构造一个零参数 Z
map[0]
如果还没有,也会这样做。
emplace
接受参数来构造一个 std::pair<const K, V>
。 std::pair
有一个带有两个元组的 std::piecewise_construct_t
标记构造函数,第一个用于构造第一个参数,第二个用于构造第二个参数。
所以 std::pair<const int, Z> test( std::piecewise_construct, std::make_tuple(0), std::make_tuple() )
就地构造了 test
s 元素,const int
是用 (0)
构造的。 Z
由 ()
.
构成
map.emplace
转发是 std::pair
构造函数的参数。
最简单的解决方案是使用operator[]
构造地图内部的值。然后你可以赋值(或者根据需要对其进行操作)。
可能以下解决方案会更好,因为 atomic 不可复制:
class Z {
std::atomic<int> i;
};
std::unordered_map<int, std::shared_ptr<Z>> map;
void test(void) {
map.emplace(0, std::make_shared<Z>()); // OK
}
我正在尝试在包含原子的映射中构造一个对象,因此它既不能复制也不能移动 AFAICT。
我对 C++ reference 的阅读是 map emplace
应该能够做到这一点。但是由于删除或不存在的构造函数,以下代码无法编译。使用 make_pair
没有帮助。
#include <atomic>
#include <unordered_map>
class Z {
std::atomic<int> i;
};
std::unordered_map<int, Z> map;
void test(void) {
map.emplace(0, Z()); // error
map[0] = Z(); // error
}
这可能吗,如果不可能,为什么不呢?
编辑:编译器是 Linux
上的 gcc 4.8.1map.emplace(std::piecewise_construct, std::make_tuple(0), std::make_tuple())
将在位置 0
.
Z
map[0]
如果还没有,也会这样做。
emplace
接受参数来构造一个 std::pair<const K, V>
。 std::pair
有一个带有两个元组的 std::piecewise_construct_t
标记构造函数,第一个用于构造第一个参数,第二个用于构造第二个参数。
所以 std::pair<const int, Z> test( std::piecewise_construct, std::make_tuple(0), std::make_tuple() )
就地构造了 test
s 元素,const int
是用 (0)
构造的。 Z
由 ()
.
map.emplace
转发是 std::pair
构造函数的参数。
最简单的解决方案是使用operator[]
构造地图内部的值。然后你可以赋值(或者根据需要对其进行操作)。
可能以下解决方案会更好,因为 atomic 不可复制:
class Z {
std::atomic<int> i;
};
std::unordered_map<int, std::shared_ptr<Z>> map;
void test(void) {
map.emplace(0, std::make_shared<Z>()); // OK
}