调用函数中结构的构造函数,C++

invoking constructors of struct in functions, C++

本文关键字:构造函数 C++ 结构 函数 调用      更新时间:2023-10-16

这是我的问题的大致代码。首先,我们有一个带有构造函数的结构:

struct Pair{
Pair(int a, int b): (first (a) , second (b) ) {}
int first;
int second;
};

用于地图

map<string, Pair> mymap;

我想在函数中初始化此映射

void f(map<string, Pair>* mymap, string c,int x, int y )
{
(*mymap)[c]=Pair(x,y);
}

但编译器首先表示找不到合适的构造函数,然后是没有为构造函数提供足够的参数。

我的一个朋友告诉我,我应该写这样的函数:

void f(map<string, Pair>& mymap, const string& c,int x, int y )
{
  if (mymap.find(c) != mymap.end()) {
    mymap[c] = Pair(x,y);
   }
}

但他无法解释为什么Type&,而不是Type*,我想澄清这一点有人能解释一下吗?

问题是映射中的operator[]要求值类型是默认可构造的。如果您不希望您的Pair是默认可构造的,则必须避免使用operator[]:

void f(map<string, Pair>& mymap, string c,int x, int y )
{
   mymap.insert( std::make_pair(c,Pair(x,y)) );
}

你可能误解了你朋友的建议。operator[]的问题不在于,如果需要创建一个新元素,它需要默认构造函数,而是在可能需要的情况下需要它。也就是说,元素是否存在并不重要。


如果你也想更新,那么你也需要考虑这个选项:

void f(map<string, Pair>& mymap, string c,int x, int y )
{
   auto res = mymap.insert( std::make_pair(c,Pair(x,y)) );
   if ( !res.second )
      res.first->second = Pair(x,y);
}

基本上,insert操作返回一对指向键的迭代器和一个bool,指示该insert是否创建了对象,或者它是否已经存在(在这种情况下,映射中的值是未修改的)。通过存储结果,我们可以进行测试,如果insert没有创建值,我们可以通过返回的迭代器更新它。

在映射上调用operator[]需要您的类型是默认可构造的。您可以通过使用map::insert或map::template

来避免这种情况

您将需要一个默认的构造函数:

Pair(): first () , second () {}

这是地图的operator[]所需要的,它会创建默认构造的mapped_type当使用不存在的密钥调用时-

和一个实现严格弱排序的小于运算符:

struct Pair {
  // as before
  bool operator<(const Pair& rhs) const {
     / some code to implement less-than
  }
};

或者,您可以将比较函子或实现严格弱排序的函数作为第三个模板参数

标准容器需要一个默认的构造函数。他们将使用operator=在构建后的某个点设置正确的值。