为什么在"形成对引用类型的引用"映射中出现错误?

22 c++ stl

如果我需要使用引用,那么替代方法是什么,而我传递的数据我无法更改类型,因此我无法真正存储指向它的指针?

码:

    #include <map>     
    #include<iostream>
    #include<string>     

    using namespace std;

    int main()
    {
       string test;
       pair<string, string> p=pair<string, string>("Foo","Bar");
       map<pair<string, string>, string&> m;
       m[make_pair("aa","bb")]=test;

       return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误:

$ g ++ MapPair.cpp /usr/include/c++/3.2.3/bits/stl_map.h:在std :: string&'MapPair.cpp的实例化中 :在函数std :: map,std :: string&,std :: less >, std :: allocator, std :: string&>>>&[std :: pair]'operator /usr/include/c++/3.2.3/bits/stl_pair.h:在全局范围:/ usr/include/c ++ /3.2.3/bits/stl_pair.h:在std :: _ Rb_tree_node的 实例化中std::map<std::pair<std::string, std::string>, std::string&, std::less<std::pair<std::string, std::string> >, std::allocator<std::pair<const std::pair<std::string, std::string>, std::string&> > >': MapPair.cpp:15:
instantiated from here /usr/include/c++/3.2.3/bits/stl_map.h:221: forming reference to reference type
int main()': MapPair.cpp:16: no match for

std::pair<const std::pair<std::string, std::string>, std::string&>': /usr/include/c++/3.2.3/bits/stl_tree.h:122: instantiated from

我做错了什么导致这种错误?

GMa*_*ckG 35

您无法存储参考.引用只是另一个变量的别名.

地图需要存储的字符串副本:

map<pair<string, string>, string> m;
Run Code Online (Sandbox Code Playgroud)

你得到那个特定错误的原因是因为在map中的某个地方,它会对mapped_type你的情况进行操作string&.其中一个操作(例如operator[],在)中将返回对以下内容的引用mapped_type:

mapped_type& operator[](const key_type&)
Run Code Online (Sandbox Code Playgroud)

与你一起mapped_type,将是:

string&& operator[](const key_type& _Keyval)
Run Code Online (Sandbox Code Playgroud)

你不能参考参考:

标准8.3.4:

不应引用引用,不引用引用数组,也不引用引用指针.


另外,我建议您使用typedef,以便您的代码更易于阅读:

int main()
{
    typedef pair<string, string> StringPair;
    typedef map<StringPair, string> StringPairMap;

    string test;

    StringPair p("Foo","Bar");
    StringPairMap m;
    m[make_pair("aa","bb")] = test;

   return 0;
Run Code Online (Sandbox Code Playgroud)

}


vol*_*evo 20

此处的答案已过时.今天我们std::reference_wrapper作为C++ 11标准的一部分:

#include <map>
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string test;
    pair<string, string> p = pair<string, string>("Foo", "Bar");
    map<pair<string, string>, reference_wrapper<string>> m;
    m[make_pair("aa", "bb")] = test;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

std :: reference_wrapper将隐式转换为对其内部类型的引用,但这在某些上下文中不起作用,在这种情况下,您需要.get()访问.

http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper


nav*_*tor 9

您可以使用boost :: reference_wrapper在STL容器中存储引用.以下是您修改的示例(未经过测试,绝对写得不是很好,只是说明了一点)

#include <map>     
#include<iostream>
#include<string>   
#include <boost/ref.hpp>



int main()
{
   typedef std::pair< std::string, std::string> PairType;
   typedef std::map< PairType, boost::reference_wrapper<std::string> > MapType;
   std::string test = "Hello there!!";
   MapType m;
   PairType pp =  std::make_pair("aa","bb");
   m.insert(std::make_pair(pp , boost::ref(test) ) );

   MapType::iterator it (m.find( pp ) );
   if(it != m.end())
   {
       std::cout << it->second.get() << std::endl;
   }

   //change test
   test = "I am different now";
   std::cout << it->second.get() << std::endl;

   return 0;
}
Run Code Online (Sandbox Code Playgroud)