C++ 在std::map中,如何编写分配器以接受键作为值';什么是构造函数参数?

C++ 在std::map中,如何编写分配器以接受键作为值';什么是构造函数参数?,c++,C++,例如: #include <map> class A { public: A(int i) {} }; std::map<int, A> as; int main() { A& a = as[1]; } #包括 甲级{ 公众: A(int i){} }; std::map as; int main(){ A&A=as[1]; } 由于A没有默认构造函数,因此此代码将无法编译 那么,如何(或者我可以?)编写一个分配器,它将通过使用1作为构造函数参数

例如:

#include <map>
class A {
 public:
  A(int i) {}
};

std::map<int, A> as;

int main() {
  A& a = as[1];
}
#包括
甲级{
公众:
A(int i){}
};
std::map as;
int main(){
A&A=as[1];
}
由于
A
没有默认构造函数,因此此代码将无法编译


那么,如何(或者我可以?)编写一个分配器,它将通过使用
1
作为构造函数参数来创建
A

您可以为添加一个包装器,该包装器使用键的值作为
try\u emplace
forwading参数,尝试在给定键处放置一个新的
元素(如果它不存在的话)。您可以在
if
语句中的初始化语句中组合结构化绑定,以稍微整齐地获取新插入的元素或访问预先存在的元素

#include <iostream>
#include <map>
#include <utility>

struct A {
  A(int i) : i_(i) {}
  int i_;
};

template <typename Key>
auto try_emplace_key_as_arg(std::map<Key, A> &m, Key &&key) {
  return m.try_emplace(key, std::forward<Key>(key));
}

template <typename Key>
void try_emplace_with_diagnostics(std::map<Key, A> &m, Key &&key) {
  if (auto [it, was_inserted] =
          try_emplace_key_as_arg(m, std::forward<Key>(key));
      was_inserted) {
    std::cout << "\nNew: " << it->second.i_;
  } else {
    std::cout << "\nAlready existed: " << it->second.i_;
  }
}

int main() {
  std::map<int, A> as{{2, A{2}}};
  try_emplace_with_diagnostics(as, 1); // New: 1
  try_emplace_with_diagnostics(as, 2); // Already existed: 2
}
#包括
#包括
#包括
结构A{
A(inti):i_ui(i){}
国际组织;
};
模板
自动尝试放置键作为参数(标准::映射和m,键和键){
返回m.try_位置(键,std::forward(键));
}
模板
无效使用诊断(std::map&m、键和键)尝试放置{
如果(自动[它,已插入]=
试着把键放在arg(m,std::forward(key));
(已插入){

std::cout您可以为添加一个包装器,该包装器尝试在给定键处放置一个新的
元素(如果它不存在)使用键的值作为
try\u emplace
forwading参数。您可以在
if
语句中的初始化语句中组合结构化绑定,以稍微整齐地获取新插入的元素或访问预先存在的元素

#include <iostream>
#include <map>
#include <utility>

struct A {
  A(int i) : i_(i) {}
  int i_;
};

template <typename Key>
auto try_emplace_key_as_arg(std::map<Key, A> &m, Key &&key) {
  return m.try_emplace(key, std::forward<Key>(key));
}

template <typename Key>
void try_emplace_with_diagnostics(std::map<Key, A> &m, Key &&key) {
  if (auto [it, was_inserted] =
          try_emplace_key_as_arg(m, std::forward<Key>(key));
      was_inserted) {
    std::cout << "\nNew: " << it->second.i_;
  } else {
    std::cout << "\nAlready existed: " << it->second.i_;
  }
}

int main() {
  std::map<int, A> as{{2, A{2}}};
  try_emplace_with_diagnostics(as, 1); // New: 1
  try_emplace_with_diagnostics(as, 2); // Already existed: 2
}
#包括
#包括
#包括
结构A{
A(inti):i_ui(i){}
国际组织;
};
模板
自动尝试放置键作为参数(标准::映射和m,键和键){
返回m.try_位置(键,std::forward(键));
}
模板
无效使用诊断(std::map&m、键和键)尝试放置{
如果(自动[它,已插入]=
试着把键放在arg(m,std::forward(key));
(已插入){

std::如果您使用的是C++17,那么使用起来不是简单得多吗?或者,如果您必须使用index,您可以使用
A&A=as.at(1);
@UnholySheep,因为如果
as[1]
存在,我就不会放置。
如果元素已经存在,则放置
不放置:“如果容器中没有具有键的元素,则将新元素插入到使用给定参数就地构造的容器中。”-我在commentAllocators中链接的文档的第一行不构造对象,而是分配内存(构造成员在C++17中不推荐,在C++20中删除)。
std::map::operator[]
要求该值是默认可构造的,不需要摆弄分配器就可以改变这一点。使用起来会不会简单得多?或者如果您使用的是C++17?或者,如果您必须使用index,您可以使用
A&A=as.at(1);
@UnholySheep,因为我不会将if
用作[1]
存在。
如果元素已经存在,则不使用emplace
方法:“如果容器中没有包含键的元素,则将新元素插入到使用给定参数就地构造的容器中。”-我在注释中链接的文档的第一行分配器不构造对象,而是分配内存(构造成员在C++17中被弃用,而在C++20中被删除)。
std::map::operator[]
要求该值是默认可构造的,任何修改分配器都不会改变这一点。