我试图更好地了解 std::unordered_map::emplace,并且我想我了解复制和移动构造函数(如果它们存在)是如何被利用的。我在下面概述了每种不同用法的相关描述。如果有人发现描述有任何问题,请告诉我。
然而,我最好奇的是,当只定义了默认和用户定义的构造函数时会发生什么?看起来默认构造函数根本没有调用,自定义构造函数只调用了ONCE,那么unordered_map中新构造元素的FooBar成员是怎么填充的呢?(我想默认/用户定义的构造函数至少被调用两次)。另外,如果 FooBar 没有定义复制和移动构造函数,下面的 3 种情况是否有任何行为差异?
注意:我知道这是一个微不足道的例子,其中深拷贝不是问题,所以复制/移动语义并没有真正产生任何显着的收益。我只是使用这个简化的例子来表达我的观点。
struct FooBar
{
FooBar()
{
printf("Foobar default constructor called\n");
};
FooBar(int* pFoo, int* pBar)
{
m_pFoo = pFoo;
m_pBar = pBar;
printf("Foobar user-defined constructor called\n");
};
FooBar(FooBar & rhs)
{
m_pBar = rhs.m_pBar;
m_pFoo = rhs.m_pFoo;
printf("Foobar copy constructor called\n");
};
FooBar(FooBar && rhs)
{
m_pBar = rhs.m_pBar;
m_pFoo = rhs.m_pFoo;
rhs.m_pBar = nullptr;
rhs.m_pFoo = nullptr;
printf("Foobar move constructor called\n");
};
int* m_pFoo;
int* m_pBar;
};
int _tmain(int argc, _TCHAR* argv[]) …Run Code Online (Sandbox Code Playgroud) 我在 unordered_map 中存储了一些中间结果。现在当试图输出它时,它显示键是按降序排列的。有没有办法以其他顺序显示它?如何?
我有一个std::unordered_map<string, std::array<int, 2>>. emplace将值放入地图的语法是什么?
unordered_map<string, array<int, 2>> contig_sizes;
string key{"key"};
array<int, 2> value{1, 2};
// OK ---1
contig_sizes.emplace(key, value);
// OK --- 2
contig_sizes.emplace(key, std::array<int, 2>{1, 2});
// compile error --3
//contig_sizes.emplace(key, {{1,2}});
// OK --4 (Nathan Oliver)
// Very inefficient results in two!!! extra copy c'tor
contig_sizes.insert({key, {1,2}});
// OK --5
// One extra move c'tor followed by one extra copy c'tor
contig_sizes.insert({key, std::array<int, 2>{1,2}});
// OK --6
// Two extra move constructors
contig_sizes.insert(pair<const string, array<int, …Run Code Online (Sandbox Code Playgroud) 我有一个数据结构,它是 unordered_map 的 unordered_map:
typedef std::unordered_map<string, int> map1;
typedef std::unordered_map<string, map1> map2;
Run Code Online (Sandbox Code Playgroud)
我想在map1中插入一个元素,而不需要使用IF语句来检查它是否已经存在。但是,我有点困惑,因为除非您已经拥有 map1 元素,否则 map2 没有值,但 map1 元素来自 map2(如果它已经存在)。
什么是最干净的方法来做到这一点?
需要为整数和一些用户定义的类-MyClass 创建unordered_map,其中MyClass 使用互斥锁进行数据访问同步,即MyClass 对象不能被复制或移动。是否可以创建这样的地图?如何使用 emplace 创建 MyClass 的对象以避免复制/移动?
template<typename T>
class MyClass {
public:
T pop() {
std::unique_lock<std::mutex> lock(m_mutex);
m_cv.wait(lock, [this]{return !m_queue.empty();});
return m_queue.pop();
}
void push(T const& x) {
{
std::unique_lock<std::mutex> lock(m_mutex);
m_queue.push(x) ;
}
m_cv.notify_one();
}
private:
std::queue<T> m_queue ;
std::mutex m_mutex ;
std::condition_variable m_cv;
};
int main(){
std::unordered_map<int, MyClass<float>> mmap;
mmap.emplace(1, MyClass<float>{});
}
Run Code Online (Sandbox Code Playgroud) 我有一张地图如下图所示.
struct B {
int b1;
int b2;
int b3;
};
struct A {
B a1;
B a2;
};
unordered_map<int, unordered_map<int, A>> outer_map;
Run Code Online (Sandbox Code Playgroud)
我用一些元素填充了这个inner_map,每个内部map对象也初始化了几个元素.
所以我的问题是如何清除outer_map,以便我可以新填充数据?
outer_map.clear()有效吗?当你在这里打电话时,内部到底发生了什么?有人可以提供一些内部细节吗?
我正在尝试创建一个无序的std::functions. 其中键是一个字符串,您将在其中查找要调用的函数,而函数是值。
我写了一个小程序:
#include <iostream>
#include <unordered_map>
#include <functional>
#include <string>
void func1()
{
std::cout << "Function1 has been called." << std::endl;
}
int doMaths(int a)
{
return a + 10;
}
int main()
{
std::unordered_map<std::string,std::function<void()>> myMap;
myMap["func1"] = func1;
}
Run Code Online (Sandbox Code Playgroud)
这编译得很好,我可以通过放置来调用该函数(但是我不确定这是否是正确的方法):
auto mapIter = myMap.find("func1");
auto mapVal = mapIter->second;
mapVal();
Run Code Online (Sandbox Code Playgroud)
然后调用该函数,但是我认为这是以创建该函数的新副本为代价的?如果我错了,请纠正我。
但是,如果我尝试这样做:myMap["doMaths"] = doMaths;由于 in 中的值myMapisstd::function<void()>>而 not ,我会收到编译器错误std::function<int(int)>>。当我这样做时,我确实得到了这个编译:myMap["doMaths"] = std::bind(doMaths,int());但是我不知道它实际上做了什么。当我尝试以与 相同的方式调用它时func1,出现编译器错误。
所以我想我有两个问题:
我如何创建一个 unordered_map 它将采用任何类型的函数作为它的值?以及如何在地图中调用该函数而不必复制该函数?
这是assigning-of-unordered-map-to-pair-of-objects的后续问题。这是一个关于编译器错误解释的问题(而不是一个重复的问题,因为该问题已经得到了完整的回答)。有人问我是否查看了错误,并发布了错误以便其他人可以从理解中受益。这是第一个错误:
#include <bits/stdc++.h>
using namespace std;
struct foo {
int n;
foo(int n): n(n) {};
// foo(): n(0) {};
};
int main(){
unordered_map<int, pair<foo,foo>> m;
m[3] = make_pair(foo(1),foo(2));
}
Run Code Online (Sandbox Code Playgroud)
这是编译后的第一个错误(暂时省略):
g++ -std=c++17 -Weffc++ -Wall -Wextra -Wsign-conversion pairs.cpp -o ../build/pairs.bin
In file included from /usr/include/c++/8/functional:54,
from /usr/include/x86_64-linux-gnu/c++/8/bits/stdc++.h:71,
from pairs.cpp:1:
/usr/include/c++/8/tuple: In instantiation of ‘std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {int&&}; long unsigned int ..._Indexes1 = {0}; _Args2 = {}; long unsigned int ..._Indexes2 …Run Code Online (Sandbox Code Playgroud) #include <iostream>
#include <unordered_map>
#include <string>
struct tree_node {
// tree_node() : attrib_val{"null"} {}
std::unordered_map<std::string, tree_node> child;
};
int main(int argc, char const *argv[])
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这段代码在我的 mac 上用 clang 编译得很好:
$ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
$ g++ -std=c++11 test.cpp
$
Run Code Online (Sandbox Code Playgroud)
在我的 linux 机器上,使用 gcc 9.1.0,我收到以下错误:
In file included from /usr/um/gcc-9.1.0/include/c++/9.1.0/bits/stl_algobase.h:64,
from /usr/um/gcc-9.1.0/include/c++/9.1.0/bits/char_traits.h:39,
from /usr/um/gcc-9.1.0/include/c++/9.1.0/ios:40,
from /usr/um/gcc-9.1.0/include/c++/9.1.0/ostream:38,
from /usr/um/gcc-9.1.0/include/c++/9.1.0/iostream:39,
from test.cpp:1:
/usr/um/gcc-9.1.0/include/c++/9.1.0/bits/stl_pair.h: In instantiation …Run Code Online (Sandbox Code Playgroud) 最近去用了std::unordered_map::erase,看到函数有一些重载:
iterator erase( const_iterator pos ); (1) (since C++11)
iterator erase( iterator pos ); (1) (since C++17)
iterator erase( const_iterator first, const_iterator last ); (2) (since C++11)
size_type erase( const key_type& key ); (3) (since C++11)
Run Code Online (Sandbox Code Playgroud)
在提到的函数返回值的描述中:
Return value
1-2) Iterator following the last removed element.
3) Number of elements removed.
Run Code Online (Sandbox Code Playgroud)
最后一个 (3),表示我们可以删除元素的数量。这是否意味着可以在地图上使用相同的键?
c++ ×10
unordered-map ×10
c++11 ×3
clang ×1
dictionary ×1
emplace ×1
g++ ×1
gcc ×1
stdarray ×1
stl ×1
struct ×1
visual-c++ ×1