单行初始化映射中的C++对象
One-line initialize a C++ object in map
初始化类并直接分配给unordered_map的正确方法是什么?
#include <string>
#include <unordered_map>
int main() {
std::unordered_map<std::string, Foo> s;
// Foo foo{1};
s["test"] = Foo(1); // this is bad
return 0;
}
福.h
class Foo {
public:
Foo(int x)
: x_(x) {}
private:
int x_;
};
现在我得到
main.cpp:19:4: note: in instantiation of member function 'std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Foo, std::hash<std::__cxx11::string>, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Foo> > >::operator[]' requested here
s["test"] = Foo(1);
^
Foo.h:3:5: note: candidate constructor not viable: requires single argument 'x', but no arguments were provided
Foo(int x)
^
Foo.h:1:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
class Foo {
^
Foo.h:1:7: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided
问题与s["test"] = Foo(1)
有关。
当你想使用operator[]
时,map中的元素必须是默认可构造的,因为它默认构造给定键的值,当它还没有出现在map中时。要么使Foo
默认可构造,要么改用insert
或emplace
。
默认可构造Foo
:
class Foo {
public:
Foo(int x = 0) // <- can be called without parameters
: x_(x) {}
private:
int x_;
};
s["test"] = Foo(1)
将在s["test"]
处默认初始化对象,然后从Foo(1)
创建的临时Foo
对象复制(或移动(分配给它。
这很糟糕,因为Foo
没有默认构造函数,因此无法对其进行默认初始化。
你可以使用unordered_map
的insert
、emplace
或try_emplace
方法之一来解决这个问题。 例如:
s.try_emplace("test", 1)
这将使用键"test"
直接构造一个新的Foo
s
对象,并将1
传递给其构造函数。
当你没有默认构造函数时,你需要使用std::map::insert
、std::map::emplace
或std::map::try_emplace
。
例如
s.emplace(std::make_pair("test", Foo(1)));
或更简单的形式
s.emplace("test", Foo(1));
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 构造对象的歧义
- 使用"std::unordereded_map"映射到"std::list"对象