当前位置: 首页 > 知识库问答 >
问题:

从地图中获取价值的最佳实践是什么?

司马英才
2023-03-14

我对函数返回有点困惑,我的目的是尽量避免复制。

我读了一些文档,告诉我不要使用reference作为map的值。

但在下面的代码中,我感到困惑。

struct BigCls {
  // this struct has a expensive constructor
  BigCls(...);
};

// solution 1
void create_function() {
  std::map<int, BigCls> m;
  m[1] = BigCls(...);
  m[2] = BigCls(...);
  ...
}

BigCls get(int a) {
  return m.at(a);
}

// solution 2
void create_function() {
  std::map<int, BigCls*> m;
  m[1] = new BigCls(...);
  m[2] = new BigCls(...);
  ...
}

BigCls* get(int a) {
  return m.at(a);
}

// solution 3
void create_function() {
  std::map<int, BigCls&> m;  // i think if map's value is reference, then the cls should be static
  // or it will fail, am i right?
  static BigCls cls(...);
  m[1] = cls;
  ...
}    
BigCls& get(int a) {
  return m.at(a);
}

哪一个最快?你认为哪一个是最好的?

共有2个答案

阎烨
2023-03-14

您不需要在映射中存储引用就可以获得对映射中值的引用。这里:

std::map<int,BigCls> m;

BigCls& get(int a) {
  return m.at(a);
}

您正在返回对映射中值的引用。如果你这样称呼它,就不会复制:

BigCls& x = get(42);

在映射中存储指针是不必要的复杂,除非您实际需要该级别的间接(例如当bigcls是多态类型时)。

哪一个最快?你认为哪一个是最好的?

这听起来像是过早的优化。根据需要副本还是引用,选择返回副本或引用。它意味着函数的不同语义。担心性能是因为您有正确的代码,并且通过分析和测量,您发现它需要改进。

宋宏儒
2023-03-14

std::map ::at

t&at(常量键和键);(1)(自C++11)
常量t&at(常量键和键)常量;(2)(自C++11)

返回对key与key等效的元素的映射值的引用。如果不存在这样的元素,则抛出std::out_of_range类型的异常。

(cppreference)

std::map::at返回元素引用,因此不存在复制行为(除非您将其返回值赋给非引用变量)。

问题中的代码有问题,m变量不应该在函数内部。

除了这个问题之外,将解决方案1中的get函数的返回类型从bigcls更改为bigcls&将是最好的解决方案。

struct BigCls {
  BigCls(...);

  int v1, v2;
};


std::map<int, BigCls> m;

void create_function() {
  m[1] = BigCls(...);
  m[2] = BigCls(...);
  ...
}

BigCls& get(int a) {
  return m.at(a);
}

void examples()
{
  int v1 = get(1).v1;

  BigCls &bigCls2 = get(2);
  int v2 = bigCls2.v2;
}
 类似资料:
  • 问题内容: 问题 从地图中获取数据 资料格式 注意 如何从上述结果中获得以下值 1.Event_dtmReleaseDate 2.strID 3.Trans_strGuestList 我试过的 res.Map(“ Event_dtmReleaseDate”); 错误:res.Map未定义(类型map [string] interface {}没有字段或方法Map) res.Event_dtmRel

  • 问题内容: 在Web应用程序(jsp /servlets)中获取EntityManagerFactory的最佳方法是什么?这是一个好方法,何时应创建/打开EntityManagerFactory实例?,还是从JNDI或其他方式获得它更好? 问题答案: 它们是重量级的,应该在应用程序范围内。因此,您需要在应用程序启动时将其打开,并在应用程序关闭时将其关闭。 该如何做取决于您的目标容器。它是否支持EJ

  • 问题内容: 我刚开始学习Go,并通读现有代码以学习“其他人的做法”。在这种情况下,遍历使用go“工作区”,尤其是与项目依赖关系有关的地方。 在处理各种Go项目时,使用一个或多个Go工作区(即$ GOPATH的定义)的常见(或存在)最佳实践是什么?我应该期望有一个类似于我所有项目的中央代码存储库的Go工作区,还是在我处理这些项目时都明确将其分解并设置$ GOPATH(有点像python) virtu

  • 所以我想在python中抓取属性值,目前我正在使用正则表达式,但它不是那么有效,所以我想知道我应该使用什么,因为许多人说正则表达式不适合这样的东西。 谢谢 这就是我想得到的。 值始终包含随机数。

  • 问题内容: 我正在构建一个基于expressjs的应用程序,我想在其中记录所有事件。我可以找到温斯顿,这似乎很酷。无论如何,我正在寻找一种方法将其连接到我的expressjs应用程序。 我还想要在应用程序内部登录。我的要求不是那么简单,所以我想将所有内容记录在我的应用程序中(不仅是请求)。 我目前的情况: server.js (我想在此级别记录http请求) 路线/something.js con

  • 问题内容: 我正在与Go一起使用MongoDB。我有以下代码: k:0 v:地图[_id:ObjectIdHex(“ 536887c199b6d0510964c35b”)transId:A000000000] 我需要从中获取切片中返回的映射值和的值。我怎样才能做到这一点? 问题答案: 我只是在猜测,但万一您只想检索所有 交易 文档并打印它们,方法如下: 假设您有一个代表您收藏的文件的结构,例如: