我在使用模板成员和使用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<<
的任何想法?
答案 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 destructed
后const 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;
}
我想这与名称解析有关。