一行初始化映射中的C++对象

一行初始化映射中的C++对象,c++,clang,c++17,C++,Clang,C++17,初始化类并直接分配给无序映射的正确方法是什么 #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; } 现在我明白了 main.cpp:19:4: note: in instantiat

初始化类并直接分配给无序映射的正确方法是什么

#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;
}
现在我明白了

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]=Foo1有关。

如果要使用运算符[],则映射中的元素必须是默认可构造的,因为当给定键在映射中尚不存在时,它默认构造该键的值。要么使您的Foo默认可构造,要么使用或

默认可构造Foo:


如果要使用运算符[],则映射中的元素必须是默认可构造的,因为当给定键在映射中尚不存在时,它默认构造该键的值。要么使您的Foo默认可构造,要么使用或

默认可构造Foo:


如果没有默认构造函数,则需要使用或

例如

还是更简单的形式

s.emplace("test", Foo(1));

如果没有默认构造函数,则需要使用或

例如

还是更简单的形式

s.emplace("test", Foo(1));
s[test]=Foo1将默认在s[test]初始化对象,然后从Foo1创建的临时Foo对象复制或移动分配给它

这会崩溃,因为Foo没有默认构造函数,所以不能进行默认初始化

你可以使用一个无序的地图或方法来解决这个问题。例如:

s.try_emplace("test", 1)
这将使用键test直接在s中构造一个新的Foo对象,并将1传递给其构造函数。

s[test]=Foo1将默认在s[test]初始化对象,然后从Foo1创建的临时Foo对象复制或移动分配给它

这会崩溃,因为Foo没有默认构造函数,所以不能进行默认初始化

你可以使用一个无序的地图或方法来解决这个问题。例如:

s.try_emplace("test", 1)
这将直接在s中使用键test构造一个新的Foo对象,并将1传递给它的构造函数。

//这很糟糕-我敢打赌,当您分析应用程序的优化构建并查找瓶颈时,它甚至不会出现在前100名列表中。别担心,如果你想说s[test]=Foo1;那么您需要一个Foo的默认构造函数,或者您的问题是关于s[test]=Foo1;?//这很糟糕——我敢打赌,当你对应用程序的优化构建进行评测并查找瓶颈时,它甚至不会出现在前100名列表中。别担心,如果你想说s[test]=Foo1;那么您需要一个Foo的默认构造函数,或者您的问题是关于s[test]=Foo1;?
s.try_emplace("test", 1)