C++ “为什么我在”中出现错误;形成对引用类型的引用“;地图?

C++ “为什么我在”中出现错误;形成对引用类型的引用“;地图?,c++,stl,C++,Stl,如果我需要使用引用,并且我传递的数据无法更改的类型,因此我无法真正存储指向它的指针,那么还有什么替代方法 代码: #包括 #包括 #包括 使用名称空间std; int main() { 串试验; 对p=对(“Foo”、“Bar”); 地图m; m[配对(“aa”、“bb”)]=试验; 返回0; } 错误: $g++MapPair.cpp /usr/include/c++/3.2.3/bits/stl_map.h: 举例说明 std::map”:MapPair.cpp:15: 从这里实例化 /u

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

代码:
#包括
#包括
#包括
使用名称空间std;
int main()
{
串试验;
对p=对(“Foo”、“Bar”);
地图m;
m[配对(“aa”、“bb”)]=试验;
返回0;
}
错误: $g++MapPair.cpp /usr/include/c++/3.2.3/bits/stl_map.h: 举例说明
std::map”:MapPair.cpp:15:
从这里实例化 /usr/include/c++/3.2.3/bits/stl_map.h:221: 形成对引用类型的引用
std::string&'MapPair.cpp:In 函数
int main()':MapPair.cpp:16:
不敌
std::map,std::string&, std::less>,
std::分配器,
std::string&>>>&[std::pair]'运算符 /usr/include/c++/3.2.3/bits/stl_pair.h: 在全球范围内: /usr/include/c++/3.2.3/bits/stl_pair.h: 在
std::pair'的实例化中:
/usr/include/c++/3.2.3/bits/stl_tree.h:122:
实例化自
std::\u Rb\u tree\u节点
我做错了什么导致了此错误?

您不能存储引用。参考文献只是一个例子

映射需要字符串的副本来存储:

map<pair<string, string>, string> m;
使用您的
映射类型
,将是:

string&& operator[](const key_type& _Keyval)
并且您不能有对引用的引用:

标准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;
intmain()
{
typedef对StringPair;
typedef映射StringPairMap;
串试验;
线对p(“Foo”、“Bar”);
StringPairMap m;
m[配对(“aa”、“bb”)]=试验;
返回0;

}

由于模板的构建方式,您不能将引用用作val。您也可以使用指针。

您可以使用boost::reference\u包装器将引用存储在STL容器中。下面是修改后的示例(没有经过测试,而且肯定写得不是很好,只是说明了一点)

#包括
#包括
#包括
#包括
int main()
{
typedef std::pairPairType;
typedef std::mapMapType;
std::string test=“你好!!”;
地图类型m;
配对类型pp=std::配对(“aa”、“bb”);
m、 插入(std::make_pair(pp,boost::ref(测试));
迭代器it(m.find(pp));
如果(it!=m.end())
{

std::cout second.get()前面的答案已经过时。今天,我们将std::reference_包装器作为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;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
串试验;
对p=对(“Foo”、“Bar”);
地图m;
m[配对(“aa”、“bb”)]=试验;
返回0;
}
std::reference\u包装将隐式转换为对其内部类型的引用,但这在某些上下文中不起作用,在这种情况下,您可以调用
.get()
进行访问


本质上,问题是你是否可以在容器中使用引用。当然,你可以,如果你正确地准备了你的类和容器。下面我用两个简单的向量容器来演示:
vectoref
,它修改了
std::vector
,另一个是
vec
,它修改了
std::vector
它是从零开始实现的

#include <iostream>
#include <vector>

// requires compilation with --std=c++11 (at least)

using namespace std;

class A {
  int _a; // this is our true data
  A *_p; // this is to cheat the compiler

  public:
  A(int n = 0) : _a(n), _p(0)
  { cout << "A constructor (" << this << "," << _a << ")\n"; }
  // constructor used by the initializer_list (cheating the compiler)
  A(const A& r) : _p(const_cast<A *>(&r))
  { cout << "A copy constructor (" << this << "<-" << &r << ")\n"; }
  void print() const {cout << "A instance: " << this << "," << _a << "\n";}
  ~A() {cout << "A(" << this << "," << _a << ") destructor.\n";}
  // just to see what is copied implicitly
  A& operator=(const A& r) {
    cout << "A instance copied (" << this << "," << _a << ")\n";
    _a = r._a; _p = r._p;
    return *this;
  }
  // just in case you want to check if instance is pure or fake
  bool is_fake() const {return _p != 0;}
  A *ptr() const {return _p;}
};

template<typename T, int sz>
class vec { // vector class using initializer_list of A-references!!
  public:
  const T *a[sz]; // store as pointers, retrieve as references
  // because asignment to a reference causes copy operator to be invoked
  int cur;
  vec() : cur(0) {}
  vec(std::initializer_list<T> l) : cur(0) {
    cout << "construct using initializer list.\n";
    for (auto& t : l) // expecting fake elements
      a[cur++] = t.ptr();
  }
  const T& operator[](int i) {return *a[i];}
  // expecting pure elements
  vec& push_back(const T& r) {a[cur++] = &r; return *this;}
  void copy_from(vec&& r) {
    for (int i = 0; i < r.cur; ++i)
      push_back(r[i]);
  }
};

template<typename T>
class vectoref : public vector<T *> { // similar to vec but extending std::vector<>
  using size_type = typename vector<T*>::size_type;
  public:
  vectoref() {}
  vectoref(std::initializer_list<T> l) {
    cout << "construct using initializer list.\n";
    for (auto& t : l) // expecting fake elements
      vector<T*>::push_back(t.ptr());
  }
  const T& operator[](size_type i) {return *vector<T*>::at(i);}
  // expecting pure elements
  vectoref& push_back(const T& r)
  { vector<T*>::push_back(&r); return *this; }
  void copy_from(const vectoref&& r) {
    for (size_type i = 0; i < r.size(); ++i)
      vectoref<T>::push_back(r[i]);
  }
};

class X { // user of initializer_list of A
  public:
  X() {}
  void f(initializer_list<A> l) const {
    cout << "In f({...}):\n";
    for (auto& a : l)
      a.ptr()->print();
  }
};

int main()
{
  A a(7), b(24), c(80);
  cout << "----------------------------------\n";
  vectoref<A> w{a,a,b,c}; // alternatively, use next line
  // vec<A,5> w{a,a,b,c}; // 5-th element undefined
  w[0].print();
  w[3].print();
  cout << "----------------------------------\n";
  X x;
  x.f({a,b,c,a,b,c,b,a});
  cout << "==================================\n";
  return 0;
}
#包括
#包括
//需要使用--std=c++11进行编译(至少)
使用名称空间std;
甲级{
int _a;//这是我们的真实数据
A*\u p;//这是为了欺骗编译器
公众:
A(int n=0):\u A(n),\u p(0)

{我可以建议读者向下滚动到。上面的答案(当我写这篇文章时)已经过时了。你是指voltrevo给出的答案。相同的链接。
#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;
}
#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;
}
#include <iostream>
#include <vector>

// requires compilation with --std=c++11 (at least)

using namespace std;

class A {
  int _a; // this is our true data
  A *_p; // this is to cheat the compiler

  public:
  A(int n = 0) : _a(n), _p(0)
  { cout << "A constructor (" << this << "," << _a << ")\n"; }
  // constructor used by the initializer_list (cheating the compiler)
  A(const A& r) : _p(const_cast<A *>(&r))
  { cout << "A copy constructor (" << this << "<-" << &r << ")\n"; }
  void print() const {cout << "A instance: " << this << "," << _a << "\n";}
  ~A() {cout << "A(" << this << "," << _a << ") destructor.\n";}
  // just to see what is copied implicitly
  A& operator=(const A& r) {
    cout << "A instance copied (" << this << "," << _a << ")\n";
    _a = r._a; _p = r._p;
    return *this;
  }
  // just in case you want to check if instance is pure or fake
  bool is_fake() const {return _p != 0;}
  A *ptr() const {return _p;}
};

template<typename T, int sz>
class vec { // vector class using initializer_list of A-references!!
  public:
  const T *a[sz]; // store as pointers, retrieve as references
  // because asignment to a reference causes copy operator to be invoked
  int cur;
  vec() : cur(0) {}
  vec(std::initializer_list<T> l) : cur(0) {
    cout << "construct using initializer list.\n";
    for (auto& t : l) // expecting fake elements
      a[cur++] = t.ptr();
  }
  const T& operator[](int i) {return *a[i];}
  // expecting pure elements
  vec& push_back(const T& r) {a[cur++] = &r; return *this;}
  void copy_from(vec&& r) {
    for (int i = 0; i < r.cur; ++i)
      push_back(r[i]);
  }
};

template<typename T>
class vectoref : public vector<T *> { // similar to vec but extending std::vector<>
  using size_type = typename vector<T*>::size_type;
  public:
  vectoref() {}
  vectoref(std::initializer_list<T> l) {
    cout << "construct using initializer list.\n";
    for (auto& t : l) // expecting fake elements
      vector<T*>::push_back(t.ptr());
  }
  const T& operator[](size_type i) {return *vector<T*>::at(i);}
  // expecting pure elements
  vectoref& push_back(const T& r)
  { vector<T*>::push_back(&r); return *this; }
  void copy_from(const vectoref&& r) {
    for (size_type i = 0; i < r.size(); ++i)
      vectoref<T>::push_back(r[i]);
  }
};

class X { // user of initializer_list of A
  public:
  X() {}
  void f(initializer_list<A> l) const {
    cout << "In f({...}):\n";
    for (auto& a : l)
      a.ptr()->print();
  }
};

int main()
{
  A a(7), b(24), c(80);
  cout << "----------------------------------\n";
  vectoref<A> w{a,a,b,c}; // alternatively, use next line
  // vec<A,5> w{a,a,b,c}; // 5-th element undefined
  w[0].print();
  w[3].print();
  cout << "----------------------------------\n";
  X x;
  x.f({a,b,c,a,b,c,b,a});
  cout << "==================================\n";
  return 0;
}