如何返回std::pair的内容

How to return the content of std::pair?

本文关键字:pair std 何返回 返回      更新时间:2023-10-16

我正在尝试返回具有intstring值的std::pair的内容。函数的返回类型应该是什么?

我尝试了intchar返回类型,但都出现了错误。我给出了以下错误:

#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
    std::pair<int,std::string>client()  
{
std::vector<std::string> most { "lion","tiger","kangaroo",
                                 "donkey","lion","tiger",
                                 "lion","donkey","tiger"
                                 };
std::map<std::string, int> src;
for(auto x:most)
    ++src[x];
std::multimap<int,std::string,std::greater<int> > dst;
std::transform(src.begin(), src.end(), std::inserter(dst, dst.begin()), 
                   [] (const std::pair<std::string,int> &p) {
                   return std::pair<int,std::string>(p.second, p.first);
                   }
                 );
std::multimap<int,std::string>::iterator it = dst.begin();
 for(int count = 0;count<3 && it !=dst.end();++it,++count)
   std::cout<<it->second<<":"<<it->first<<std::endl;
 return *it;  
}
int main()
{
std::multimap<int,std::string>::const_iterator rec;
rec= client();  // Error  no match for ‘operator=’ in ‘rec = client()()’
std::multimap<int,std::string>::iterator it = rec.begin();  //error: ‘std::multimap<int, std::basic_string<char> >::const_iterator’ has no member named ‘begin’
 for(int count = 0;count<3 && rec !=it.end();++it,++count) // error: has no member named 'end' 
   std::cout<<rec->second<<":"<<rec->first<<std::endl;
}

只返回int&std::string本身因为multimap包含作为其元素的

std::pair<int,std::string> client(){
//...  
}

如果您想返回映射条目(即键和值),那么只需使用std::pair<int, std::string>作为返回类型,就像其他答案所提到的那样。

如果只想返回密钥,请返回it->first(并使用int作为返回类型)。如果只想返回值,请返回it->second(并使用std::string作为返回类型)。

如果您想从std::map返回a值,我不会显式使用std::pair(尽管这样做非常好)。就我个人而言,我会使用std::map::value_type,它表示映射中存储的值的类型(注意:所有容器都有一个名为value_type的类型成员,它表示要存储的类型)。

std::multimap<int,std::string>::value_type client()
{
     // STUFF
     std::multimap<int,std::string>::iterator it = dst.begin();
     // STUFF;
     return *it;   // Note: this is UB if it == dst.end()
}

我使用value_type而不是std::pair的原因是,通常我不会使用显式类型,而是会创建typedef(所以看起来是这样的)。

typedef std::multimap<int,std::string>  MapForX; // Modification to map here
                                                 // Will automatically roll threw all
                                                 // the following code as everything
                                                 // is defined in terms of `MapForX`
MapForX::value_type client()
{
     // STUFF
     MapForX::iterator it = dst.begin();
     // STUFF;
     return *it;   // Note: this is UB if it == dst.end()
}

现在,如果我更改MapForX的类型。然后我只需要更改一件事(单个typedef)。如果返回std::pair<int,std::string>,则必须在两个位置进行更改(typedef和返回值)。对我来说,这是多余的改变,可能会引发问题。

作为演示:如果您返回std::pair<int, std::string>,您的代码如下所示:

typedef std::multimap<int,std::string>  MapForX; // Modification to map here
                                                 // Will automatically roll threw MOST
                                                 // the following code.
// But notice this return type is not defined in terms of MapForX
// Thus if you change MapForX you will also need to change the return type.
// to match the correct type.
std::pair<int, std::string> client()
{
     // STUFF
     MapForX::iterator it = dst.begin();
     // STUFF;
     return *it;   // Note: this is UB if it == dst.end()
}

这非常有效。但在未来,你必须做出一些改变。你也更改了地图的类型int => MySpecialType。现在,在我的第二个示例(使用typedef)中,您只需要进行一次更改(在MapForX中)。在上面的例子中,您需要做两个更改(一个用于MapForX,另一个用于返回类型的std::pair)。

@Martin York:你的意图很好,但你有没有对照现实检查过?因为value_type导出为std::pair<const key_type, mapped_type>:

https://en.cppreference.com/w/cpp/container/map

如果您从迭代器返回一对的副本,这可能会起作用。如果在函数中构造该对,然后尝试填充它,则不会起作用,因为first无法修改。

当目标是避免两次k/v类型时:

using the_map_value_type = std::pair<the_map::key_type, the_map::mapped_type>

然后使用此类型作为函数结果。当然,只有在像detached_value_type这样的导出在STL中消除了疏忽之前。