在 map 中一行初始化一个 C++ 对象

1 c++ clang c++17

初始化类并直接分配给 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;
}
Run Code Online (Sandbox Code Playgroud)

foo.h

class Foo {
  public:
    Foo(int x)
      : x_(x) {}

  private:
    int x_;
};
Run Code Online (Sandbox Code Playgroud)

现在我得到

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
Run Code Online (Sandbox Code Playgroud)

问题与s["test"] = Foo(1).

for*_*818 6

当您要使用时operator[],映射中的元素必须是默认可构造的,因为当映射中尚不存在给定键时,它会默认构造给定键的值。要么使您的Foo默认构造可构造,要么使用insertemplace代替。

默认可构造Foo

class Foo {
  public:
    Foo(int x = 0)   // <- can be called without parameters
      : x_(x) {}

  private:
    int x_;
};
Run Code Online (Sandbox Code Playgroud)