模板运算符<<重载和make_pair

时间:2011-02-16 12:05:53

标签: c++ templates operator-overloading

我在使用模板成员和使用make_pair重载运算符时遇到了一些问题:

class MyArchive
{
    public:
    template <class C> MyArchive & operator<< (C & c)
    {

        return (*this);
    }
};

class A
{

};

int main()
{

    MyArchive oa;
    A a;
    oa << a; //it works
    oa << std::make_pair(std::string("lalala"),a); //it doesn't work
    return 0;
}

我得到了有趣的错误:

/home/carles/tmp/provaserialization/main.cpp: In function ‘int main()’:
/home/carles/tmp/provaserialization/main.cpp:30: error: no match for ‘operator<<’ in ‘oa << std::make_pair(_T1, _T2) [with _T1 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _T2 = A]((a, A()))’
/home/carles/tmp/provaserialization/main.cpp:11: note: candidates are: MyArchive& MyArchive::operator<<(C&) [with C = std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, A>]

关于为什么在第二种情况下找不到operator<<的任何想法?

3 个答案:

答案 0 :(得分:4)

operator<<的参数应为const

template <class C> MyArchive & operator<< (const C & c)

因为std::make_pair返回一个无法绑定到非const参数的临时对象。但是临时对象可以绑定到const参数,从那时起临时对象的生命延长,直到被调用函数结束。


一个简单的演示:

template<typename T>
void f(T & c) { cout << " non-const parameter" << endl; }

template<typename T>
void f(const T & a) { cout << "const parameter" << endl; }

int main() 
{
     f(make_pair(10,20.0)); //this calls second function!
}

输出:

  

const参数

请在此处查看输出:http://www.ideone.com/16DpT

编辑:

当然,上面的输出只解释了临时与const-parameter绑定的功能。它没有证明延长寿命。以下代码演示了生命延长:

struct A 
{
  A() { cout << "A is constructed" << endl; }
  ~A() { cout << "A is destructed" << endl; }
};

template<typename T>
void f(T & c) { cout << " non-const parameter" << endl; }

template<typename T>
void f(const T & a) { cout << "const parameter" << endl; }

int main() 
{
     f(A()); //passing temporary object!
}

输出:

  

A构造了   const参数
  A被破坏

函数打印A is destructedconst parameter表明A的生命延长到被调用函数结束的事实!

ideone上的代码:http://www.ideone.com/2ixA6

答案 1 :(得分:2)

使用“C const&amp; c”而不是“C&amp; c”

从make_pair返回的临时对不能绑定到运算符&lt;&lt ;,期望的引用,只能绑定到const引用。

答案 2 :(得分:-1)

这确实有效:

#include <utility>
#include <string>

class MyArchive
{
  public:
  template <class C> MyArchive & operator<< (C & c)
  {
    return (*this);
  }
};

class A
{

};

int main()
{
  MyArchive oa;
  A a;
  oa << a; //it works
  oa << (std::make_pair(std::string("lalala"),a)); //it works
  return 0;
}

我想这与名称解析有关。