unordered_map 似乎没有返回对 [] 运算符的引用

Posted

技术标签:

【中文标题】unordered_map 似乎没有返回对 [] 运算符的引用【英文标题】:unordered_map doesn't seem to return reference on [] operator 【发布时间】:2014-03-29 00:54:20 【问题描述】:

我目前有一个数据库类,其中包含一些包含数据库变量的无序映射。我已经编写了用于添加和删除变量的函数,但现在想要一种轻松访问和修改它们的方法。

我的功能是这样的:

template<typename T>
T &get(const  std::string &name)
    if(typeid(T) == typeid(int))
        return this->ints[name];
    else if(typeid(T) == typeid(float))
        return this->floats[name];

     ... ect ...

如果给出了无效类型,则抛出错误。

intsstd::unordered_map&lt;std::string, int&gt; 类型 和floats 定义相同。

在我看来,这看起来是正确的。但是当我尝试运行它时,我收到以下错误:

database.hpp:98: error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'

看起来无序映射没有返回引用,这是什么问题?

【问题讨论】:

ints的声明是什么? subscript operator 应该返回参考 unordered_map 我知道它应该,但在这种情况下似乎没有(或者至少将引用转换为值)。 当你用一种类型实例化你的代码时,你也会得到所有其他类型的返回语句。我猜您为您的实例之一获得的组合之一会导致问题。 为什么不声明unordered_map&lt;string, T&gt; store;然后返回store[name]; @BartoszKP:不是“组合之一”。他们都是。隐式转换会创建一个临时的,不能通过引用返回(您也不想这样做,因为它的生命周期在函数返回之前结束)。 【参考方案1】:

取消 C# 和 Java 泛型,可以专门化 C++ 模板。强烈建议不要按照您的方式测试类型。

如果您使用专业化,就不会遇到这个问题,因为它与 BartoszKP 评论的转换有关。

template<typename T>
T& get(const std::string &name);

在类之外,但仍在标题内:

template<>
int& ClassName::get<int>(const std::string &name)  return ints[name]; 

template<>
float& ClassName::get<float>(const std::string &name)  return floats[name]; 

【讨论】:

究竟是谁强烈反对它?我更喜欢代码更通用,这样我就可以添加另一个类型检查而不是另一个具有不同专业化的函数定义。 @CoffeeandCode:您无法解决的编译器错误消息对您来说还不够强烈吗?我从未见过 任何 熟练的 C++ 程序员使用 typeinfo 结构的比较。我见过专业化,我见过使用 enable_if&lt;same&lt;&gt;&gt; 禁用的重载 @CoffeeandCode Chain of if 语句本身就是一种代码味道。将它与后续的运行时类型检查结合起来并没有让它变得更好,更微妙。 我不喜欢对代码的更改,但编译器错误不是您可以完全解决的问题。暗示我不是熟练的 C++ 程序员有点粗鲁:L @CoffeeandCode:你的代码让我做鬼脸的另一件事是它看起来像是没有使用虚拟调度。 (当然,虚拟函数不是这里的解决方案)

以上是关于unordered_map 似乎没有返回对 [] 运算符的引用的主要内容,如果未能解决你的问题,请参考以下文章

将 unordered_map 分配给一对对象

为啥我不能更改 unordered_map 返回的对象的成员变量?

unordered_map 如何在内部使用其哈希?

有没有办法在 unordered_map 的某个位置插入元素?

如何在没有编译器警告的情况下返回对空字符串的 const 引用?

unordered_map:如果键不在地图中,返回啥?