Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::map Ilitazion(仅一次)_C++_Map_Std_Garbage - Fatal编程技术网

C++ std::map Ilitazion(仅一次)

C++ std::map Ilitazion(仅一次),c++,map,std,garbage,C++,Map,Std,Garbage,我有一个使用std::map转换数据的函数 struct HistoParameter { int nbins; float first; float last; HistoParameter(int _nbins, int _first, int _last) : nbins(_nbins), first(_first), last(_last) {}; }; HistoParameter* variable_to_parameter(char* var_name)

我有一个使用std::map转换数据的函数

struct HistoParameter
{
  int nbins;
  float first;
  float last;
  HistoParameter(int _nbins, int _first, int _last) :
    nbins(_nbins), first(_first), last(_last) {};
};

HistoParameter* variable_to_parameter(char* var_name)
{
  std::map<const std::string, HistoParameter*> hp;
  hp[std::string("ph_pt")] = new HistoParameter(100,0,22000);
  hp[std::string("ph_eta")] = new HistoParameter(100,-3,3);
  // ...
  return hp[var_name];
}
struct HistoParameter
{
int nbins;
先浮;
最后漂浮;
HistoParameter(int_nbins,int_first,int_last):
nbins(_nbins),first(_first),last(_last){};
};
HistoParameter*变量到参数(char*var\u名称)
{
std::map hp;
hp[std::string(“ph_pt”)]=新的组织参数(100,022000);
hp[std::string(“ph_eta”)]=新的组织参数(100,-3,3);
// ...
返回hp[var_name];
}
我的结构很轻,但它可能很重。问题是,每次我调用这个函数时,它都会创建很多HistoParameter对象,也许切换情况更有效。第一个问题:我在制造垃圾

第二种解决方案:

bool first_time = true;
HistoParameter* variable_to_parameter(char* var_name)
{
  static std::map<const std::string, HistoParameter*> hp;
  if (first_time)
    {
  hp[std::string("ph_pt")] = new HistoParameter(100,0,22000);
  hp[std::string("ph_eta")] = new HistoParameter(100,-3,3);
  // ...
    }
  first_time = false;
  return hp[var_name];
bool first\u time=true;
HistoParameter*变量到参数(char*var\u名称)
{
静态std::map hp;
如果(第一次)
{
hp[std::string(“ph_pt”)]=新的组织参数(100,022000);
hp[std::string(“ph_eta”)]=新的组织参数(100,-3,3);
// ...
}
第一次=错误;
返回hp[var_name];

可以吗?更好的解决方案?

第一个解决方案会产生大量垃圾。为什么不按值返回该类?它非常轻量级,而且不必动态分配

HistoParameter variable_to_parameter(char* var_name)
{
  static std::map<const std::string, HistoParameter> hp;
  if ( hp.empty() )
  {
    hp.insert( std::make_pair( "ph_pt", HistoParameter(100,0,22000) ) );
    hp.insert( std::make_pair( "ph_eta", HistoParameter(100,-3,3) ) );
  //...
  }
  return hp[var_name];
}
…如果您希望它不可变,甚至可以添加一个
const


Edit:根据Niel的建议,添加了make\u pair。

第一个解决方案会产生大量垃圾。为什么不按值返回类呢?它非常轻量级,不必动态分配

HistoParameter variable_to_parameter(char* var_name)
{
  static std::map<const std::string, HistoParameter> hp;
  if ( hp.empty() )
  {
    hp.insert( std::make_pair( "ph_pt", HistoParameter(100,0,22000) ) );
    hp.insert( std::make_pair( "ph_eta", HistoParameter(100,-3,3) ) );
  //...
  }
  return hp[var_name];
}
…如果您希望它不可变,甚至可以添加一个
const


编辑:按照Niel的建议添加了make\u pair。

第二种解决方案对我来说似乎没问题-你可以说:

if ( hp.empty() ) {
   // populate map
}
我也会考虑让它成为一个价值地图而不是指针——我看不到你需要在这里动态分配:

 std::map <std::string, HistoParameter> hp;
注意,您不需要显式的std::string转换。或者更好:

 hp.insert( std::make_pair( "ph_pt", HistoParameter(100,0,22000 )));

第二个解决方案对我来说似乎没问题——你可以说:

if ( hp.empty() ) {
   // populate map
}
我也会考虑让它成为一个价值地图而不是指针——我看不到你需要在这里动态分配:

 std::map <std::string, HistoParameter> hp;
注意,您不需要显式的std::string转换。或者更好:

 hp.insert( std::make_pair( "ph_pt", HistoParameter(100,0,22000 )));

我有一个std::map成员和do

InitializeHistoParameter() 
{
   myMap["ph_pt"] = new ...
   myMap["ph_eta"] = new ...
}
然后

HistoParameter* variable_to_parameter(char* var_name) 
{
    return myMap[var_name];
}

我有一个std::map成员和do

InitializeHistoParameter() 
{
   myMap["ph_pt"] = new ...
   myMap["ph_eta"] = new ...
}
然后

HistoParameter* variable_to_parameter(char* var_name) 
{
    return myMap[var_name];
}

您的第二个解决方案肯定会提高效率,但不是(至少在IMO)最好的实现。首先,它使
First\u time
公开可见,尽管实际上只有
variable\u to\u parameter
关心它。您已经在函数中设置了
hp
一个静态变量,
First\u time
也应该是

第二,我不会对HistoParameter值使用指针和/或动态分配。在一个int和两个float时,根本没有理由这样做。如果你真的传递它们太多以至于复制成为一个问题,你可能最好使用某种智能指针类而不是原始指针——后者更difF使用起来很困难,使异常安全更困难

第三,我会考虑是否将ValueLytoTo参数变成一个函数而不是函数是值得的。在这种情况下,你会在cTor中初始化映射,这样你就不用每次检查它是否初始化了<代码>操作程序()。调用了。您也可以通过在functor中使用静态映射将两者结合起来。如果不存在静态映射,则由functor对其进行初始化,运算符()只执行查找


最后,我要注意的是,
map::operator[]
主要用于插入项目——如果项目不存在,它将使用指定的键创建项目,但在查找项目时,通常不希望创建项目。为此,通常最好使用
map.find()
相反。

您的第二个解决方案肯定会提高效率,但事实并非如此(至少在IMO)最好的实现。首先,它使
First\u time
公开可见,尽管实际上只有
variable\u to\u parameter
关心它。您已经在函数中设置了
hp
一个静态变量,
First\u time
也应该是

第二,我不会对HistoParameter值使用指针和/或动态分配。在一个int和两个float时,根本没有理由这样做。如果你真的传递它们太多以至于复制成为一个问题,你可能最好使用某种智能指针类而不是原始指针——后者更difF使用起来很困难,使异常安全更困难

第三,我会考虑是否将ValueLytoTo参数变成一个函数而不是函数是值得的。在这种情况下,你会在cTor中初始化映射,这样你就不用每次检查它是否初始化了<代码>操作程序()。调用了。您也可以通过在functor中使用静态映射将两者结合起来。如果不存在静态映射,则由functor对其进行初始化,运算符()只执行查找


最后,我要注意的是,
map::operator[]
主要用于插入项目——如果项目不存在,它将使用指定的键创建项目,但在查找项目时,通常不希望创建项目。为此,通常最好使用
map.find()
相反。

无论哪种方式,都会造成内存泄漏。 每次调用
=
运算符时,例如:

hp[std::string("ph_pt")] = new HistoParameter(100,0,22000);
您正在创建一个新的HistoParameter对象,并将键“ph”与这个最近的对象配对,使前一个对象悬空。 如果每次都创建一个新对象是您的实际意图,那么您可能需要调用

delete hp[std::string("ph_pt")]; 
在执行
新建操作之前

我的建议是尽可能避免原始的
新的
操作