2012-07-27 79 views
1

这里是我的问题的近似代码。首先,我们有一个构造一个结构:调用struct函数的构造函数,C++

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); 
    } 
} 

但他无法解释为何类型&应在此处使用的,而不是类型 *,和我想澄清这一点。有人可以解释吗?

+0

@philippe我看不出有什么帮助。 – 2012-07-27 15:58:10

+1

1.你的朋友复制了一些已经假定在那里的代码。无论如何,地图需要找到密钥才能进行插入。 2.在这种情况下,引用或指针并不重要。 3.您需要运营商[]的默认ctor来运行 4.我太害怕以此作为答案。所以可能还活着吃我。 – nurettin 2012-07-27 16:03:04

+0

@pwned:你不应该害怕,所以我会提高答案 - 我基本上也回答了这个问题。对不起,如果你以前有过不愉快的经历,并希望能在短时间内得到一些答案:) – 2012-07-27 16:05:33

回答

3

的问题是,在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操作返回一对在关键指向迭代器,并表示如果这是一个布尔insert创建了该对象,或者它已经存在(在这种情况下,映射中的值是未修改的)。通过存储结果,我们可以测试,如果insert没有创建值,我们可以通过返回的迭代器更新它。

+0

我认为这不会更新地图中的元素,而他的最初想法可以做到这一点(例如,如果Pair具有默认的构造函数)。 – 2012-07-27 16:11:46

0

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

+1

无论如何,它需要一个'operator []'。他可以在C++ 11中使用'insert'甚至'emplace'。 – Xeo 2012-07-27 15:59:00

+0

@Xeo,我的意思是'operator ='被包含的类型,而不是容器本身。 – 2012-07-27 16:01:08

+0

他们没有,真的..在这种情况下 - 不要实例化operator []'并且你没有默认的构造函数就行了。 – 2012-07-27 16:12:34

2

在地图上调用operator[]将需要您的类型为默认可构造。您可以通过使用map::insertmap::emplace

+0

谢谢,我不知道这件事! – gartenzwerg 2012-07-27 16:19:17

2

您将需要一个默认contrructor:

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

这需要对地图的operator[],它创建了一个缺省构造时,与不存在的密钥 -

和一个叫 mapped_type 执行的小于运营商 strict weak ordering

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

或你可以传递一个比较仿函数或者功能实现为严格的弱排序,作为第三个模板参数 。

+0

对不起,我不明白为什么我需要在这里订购操作员? – gartenzwerg 2012-07-27 16:20:33

+0

我不相信你会这样做。 – jahhaj 2012-07-27 17:20:35

+0

@gartenzwerg你不需要它,我的坏。你只需要订购,如果你的类型是地图的关键字,或者你想把它放在'std :: set'中 – juanchopanza 2012-07-28 07:16:47