如何用构造函数创建一个以class为值的c++映射



我有一个有构造函数的类。我现在需要用它作为一个值来做一个映射我该怎么做呢?现在没有构造函数,我做。

#include <iostream>
#include <map>
using namespace std;
class testclass {
public:
int x = 1;
};
int main()
{
map<int,testclass> thismap;
testclass &x = thismap[2];
}

如果我添加了一个带参数的构造函数,我如何将它们添加到映射中?我需要输入

#include <iostream>
#include <map>
using namespace std;
class testclass {
public:
int x = 1;
testclass(int arg) {
x = arg;
}
};
int main()
{
map<int,testclass> thismap;
testclass &x = thismap[2];
}

这显然是行不通的,因为它需要一个参数,但我想不出一个方法来做到这一点。

这就是您如何将自己类的项添加到映射中的方法。注意:为了更好地显示差异,我在testclass中使用了字符串键和值之间/类

#include <iostream>
#include <string>
#include <map>
class testclass
{
public:
explicit testclass(const std::string& name) :
m_name{ name }
{
};
const std::string& name() const
{
return m_name;
}
private:
std::string m_name;
};
int main()
{
std::map<int, testclass> mymap;
// emplace will call constructor of testclass with "one", and "two"
// and efficiently place the newly constructed object in the map
mymap.emplace(1, "one"); 
mymap.emplace(2, "two");
std::cout << mymap.at(1).name() << std::endl;
std::cout << mymap.at(2).name() << std::endl;
}

使用std::map::operator[]要求映射类型是默认可构造的,因为它必须能够构造一个不存在的元素。

如果您的映射类型不是默认可构造的,您可以使用std::map::emplace添加元素,但您仍然不能使用std::map::operator[]进行搜索,您将需要使用std::map::find()左右。

这是std::map(和其他std容器非常相似)的一个相当明显的特性。它们的一些操作有充分的理由要求特定的类型要求。

按照您的建议创建这样的映射是没有问题的,但是,您被限制为不需要潜在默认构造的方法调用。operator[]就是这样一个方法,因为在没有找到元素的情况下,它被创建。这在你的例子中是行不通的。只要使用其他对地图使用影响不大的方法,你仍然可以成功:

#include <iostream>
#include <map>
using namespace std;
class testclass {
public:
int x = 1;
testclass(int arg) {
x = arg;
}
};
int main()
{
map<int,testclass> thismap;
thismap.insert( {2, testclass(5)} );

auto element2 = thismap.find(2);
if (element2 != thismap.end()) {
testclass& thiselement = element2->second;
cout << "element 2 found in map, value=" << thiselement.x << endl;
}
auto element5 = thismap.find(5);
if (element5 == thismap.end()) {
cout << "no element with key 5 in thismap. Error handling." << endl;
} 
}

主要问题:避免operator[].

注意:

看看其他非常好的答案,有很多方法可以在没有默认构造的情况下使用。没有"权利"这个词;倒霉透顶或"因为这完全取决于您的应用程序。atemplace是非常可取的例子。

最新更新