我想将一个对象置于std::map
其构造函数不带任何参数的对象中.但是,std::map::emplace
除了密钥之外,似乎还需要至少一个额外的参数.那么如何将零参数转发给构造函数呢?
Bri*_*ian 53
元素类型std::map<K, V>
实际上是std::pair<K, V>
,所以当你进入地图时,参数将被转发给构造函数std::pair
.这就是为什么你不能只传递密钥:std::pair<K, V>
不能用单个参数构造(除非它是另一对相同的类型.)你可以传递零参数,但是密钥将被初始化,这可能是不是你想要的.
在大多数情况下,移动值将很便宜(并且键很小并且可以复制),你应该真的只做这样的事情:
M.emplace(k, V{});
Run Code Online (Sandbox Code Playgroud)
V
映射类型在哪里.它将被初始化并移动到容器中.(此举甚至可能被忽略;我不确定.)
如果你不能移动,并且你真的需要V
就地构建,你必须使用分段构造构造函数......
M.emplace(std::piecewise_construct, std::make_tuple(k), std::make_tuple());
Run Code Online (Sandbox Code Playgroud)
这导致使用零参数(值初始化)std::pair
构造第一个元素k
和第二个元素.
Pra*_*ian 17
你可以明确地创建pair
并传递至map::emplace
,或使用分段施工构造的std::pair
.
struct foo {};
std::map<int, foo> m;
m.emplace(std::pair<int, foo>(1, {}));
m.emplace(std::piecewise_construct,
std::forward_as_tuple(2),
std::forward_as_tuple());
Run Code Online (Sandbox Code Playgroud)
我有同样的问题,当我不得不创建std::map
的std::mutex
对象.问题是std::mutex
既不可复制也不可移动,所以我需要"就地"构建它.
接受的答案对于这种情况不起作用(M.emplace(k, V{});
需要V可以移动).而且我不想使用复杂且不太可读的std::piecewise_construct
选项(参见上面的其他答案).
我的解决方案更简单 - 只需使用operator[]
- 它将使用其默认构造函数创建值并返回对它的引用.或者它只是找到并返回对现有项目的引用,而不创建新项目.
std::map<std::string, std::mutex> map;
std::mutex& GetMutexForFile(const std::string& filename)
{
return map[filename]; // constructs it inside the map if doesn't exist
}
Run Code Online (Sandbox Code Playgroud)
在C ++ 17中,您可以使用std::map::try_emplace
,它在std::piecewise_construct
内部使用,看起来并不那么麻烦。它还将键作为第一个参数(而不是std::pair::pair()
像将所有内容一样转发emplace
)。
#include <map>
struct A {
A() = default;
};
int main()
{
std::map<int, A> map;
map.emplace(std::piecewise_construct,
std::forward_as_tuple(10),
std::forward_as_tuple());
// ...vs...
map.try_emplace(10);
}
Run Code Online (Sandbox Code Playgroud)
现场例子。
归档时间: |
|
查看次数: |
12672 次 |
最近记录: |