我有一个嵌套的无序映射,它在C ++ 11中包含一个自定义对象。它看起来与此类似:
std::unordered_map<std::string, std::unordered_map<std::string, CustomClass>>
此自定义类没有移动构造函数,也不能有隐式构造函数。我在尝试分配到这个结构时遇到错误:
storageStruct[string_1][string_2].function(parameter);
由于它进入模板,实际的错误链解释真的很长,但这是我觉得最适用的那个:
候选构造函数(隐式移动构造函数)不可行:需要1个参数,但提供0
我不想移动这个对象,只是简单地调用它的成员函数。我该如何避免这种不必要的举动?
答案 0 :(得分:5)
std::unordered_map::operator[]
需要无中心地创建一个元素,即值必须是默认的可构造的。移动构造函数只是一个候选者。提供默认构造函数或不使用operator[]
(您可以使用unordered_map::find
查找元素,使用unordered_map::insert
来插入元素。)
答案 1 :(得分:2)
它不是试图移动任何东西。模板的特定成员函数可能需要其模板参数类型中的额外行为。 std::unordered_map::operator[]
的使用要求封闭类型为DefaultConstructible
,因为如果不存在,则指定创建元素。
如果您确定存在string_1
和string_2
,则可以从operator[]
更改为at
。抛出std::out_of_range
而不是创建元素,因此它不需要保持的类型为DefaultConstructible
。它也有const
重载,而operator[]
没有。
如果你不想投掷的可能性(也许你不确定字符串是否存在)那么你可以使用find
,正如其他答案所解释的那样。
答案 2 :(得分:1)
如何避免这种不必要的举动?
std::unordered_map::operator[]
变异容器(如果它不存在则插入一个空元素),所以你应该使用只读接口:
auto f1 = storageStruct.find( string_1 );
if( f1 != storageStruct.end() ) {
auto f2 = f1->second.find( string_2 );
if( f2 != f1->second.end() )
f2->second.function( parameter );
}