C++ unordered_map::insert 无法编译

C++ unordered_map::insert won't compile

提问人:UserX 提问时间:11/27/2019 最后编辑:UserX 更新时间:12/14/2019 访问量:346

问:

我只需要一个从一个浮点到另一个浮点的哈希映射。应该很简单,不是吗?编译器就是不接受它:

声明:

unordered_map<float, float> m_mffPhotoPeakMap;

用:

float CProductSpecs::AddToMap(float fEnergy, float returnedValue) const
{
    auto pair = make_pair(fEnergy, returnedValue);
    m_mffPhotoPeakMap.insert(pair);                 // Error!  (First attempt)
    m_mffPhotoPeakMap[fEnergy] = returnedValue;     // Error!  (Second attempt)
    return returnedValue;
}

错误消息(第一次尝试):

Severity    Code    Description Project File    Line    Suppression State
Error   C2663   'std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::insert': 6 overloads have no legal conversion for 'this' pointer

错误消息(第二次尝试):

Severity    Code    Description Project File    Line    Suppression State
Error   C2678   binary '[': no operator found which takes a left-hand operand of type 'const std::unordered_map<float,float,std::hash<float>,std::equal_to<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' (or there is no acceptable conversion)     

错误消息对我来说没有意义 - 语法似乎是正确的。谁能告诉我我做错了什么?

C++(英语:C++) 常数 可变

评论

4赞 Fred Larson 11/27/2019
就是那个.你答应过你不会改变对象,而你正在尝试改变对象。编译试图防止你违背诺言。const
1赞 Slava 11/27/2019
insert显然会修改映射,因此您不能在方法中这样做(除非该成员是可变的)const
4赞 HolyBlackCat 11/27/2019
不要添加到问题标题中,也不要为问题添加解决方案。相反,通过单击左侧的绿色勾号来接受对您帮助最大的答案。(如果你认为它们都不值得,你可以自己写。这是指示您的问题已解决的预期方式。[SOLVED]
2赞 Algirdas Preidžius 11/27/2019
1)“解决方案是<......>“您遇到的问题没有在问题中以最小可重复示例的形式进行描述,因此不清楚这是如何解决您的问题。2)您可以自己回答您的问题。你不应该把答案放在问题中。
1赞 HolyBlackCat 11/27/2019
另外,请参阅 meta.stackoverflow.com/questions/328379/...

答:

8赞 jwezorek 11/27/2019 #1

您正在成员函数中尝试更改成员变量。const

使 CProductSpecs::AddToMap 不是 。const

评论

1赞 jwezorek 11/27/2019
const_cast......但不要。重新设计你的代码,使其常量正确,或者只是把所有的常量都丢弃。
3赞 Fred Larson 11/27/2019
@UserX 这是没有意义的。听起来您的代码存在更广泛的一致性正确性问题。AddToMap()const
1赞 Algirdas Preidžius 11/27/2019
@UserX “AddToMap 需要是常量的,因为它是从 const 方法返回的”这是什么意思?我可以想象几种可能性,它们都没有阻止你放弃.请提供最小的可重复示例,因为目前似乎是 XY 问题const
2赞 Algirdas Preidžius 11/27/2019
@UserX 从技术上讲,可以帮助您避免编译错误,但可能会导致代码中出现未定义的行为,因此“不要”部分。const_cast
1赞 jwezorek 11/27/2019
有什么东西返回了成员函数?
3赞 Vlad from Moscow 11/27/2019 #2

该函数被声明为常量非静态成员函数,

float CProductSpecs::AddToMap(float fEnergy, float returnedValue) const
                                                                  ^^^^^

因此,您不能使用该函数来更改常量对象的数据成员。只有在使用存储类说明符声明数据成员时,才能执行此操作。m_mffPhotoPeakMapmutable

0赞 UserX 11/27/2019 #3

解决方案是将 AddToMap() 和 map 放入一个单独的类中,该类可以从 const 方法调用。

评论

0赞 Some programmer dude 11/27/2019
这似乎是解决不良设计的解决方案。也许你应该退后几步,重新思考你在做什么,你的需求,以及你为什么一开始就标记这个函数。const
0赞 UserX 11/27/2019
@Someprogrammerdude:这是一个庞大的、常量正确的类中的优化。我不认为设计不好:1.类仍然是常量正确的,2.缓存是自包含的,3.缓存以避免重新计算,将整体操作速度提高了10%以上,这很重要。
0赞 UserX 12/14/2019 #4

我找到了一个更好的解决方案:将映射声明为“可变”,使其成为 const 属性的例外:

mutable unordered_map<float, float> m_mffPhotoPeakMap;