模板运算符 <<重载和 make_pair

发布于 2024-10-17 23:06:50 字数 1068 浏览 2 评论 0 原文

我在使用模板成员重载运算符和使用 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<<的任何想法?

I have some problems overloading operators with template members and using 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;
}

I get this interesting error:

/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>]

Any ideas about why it doesn't find operator<< in the second case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冰之心 2024-10-24 23:06:50

operator<< 的参数应该是 const

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

因为 std::make_pair 返回一个临时对象,不能绑定到非常量参数。但是临时对象可以绑定到 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!
}

输出:

常量参数

自己在这里查看输出: http://www.ideone.com/16DpT

编辑:

当然,上面的输出仅解释了 tempor 绑定到具有 const 参数的函数。它没有表现出寿命的延长。以下代码演示了寿命延长:

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 已构造
常量参数
A被破坏

在函数打印 const 参数之后,A 被析构这一事实表明 A 的生命周期被延长到被调用函数的末尾!

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

The parameter of operator<< should be const :

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

Because std::make_pair returns a temporary object which cannot be bound to non-const parameter. But a temporary object can be bound to a const parameter, since then the life of the temporary extends, till the end of the called function.


A simple demonstration:

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!
}

Output:

const parameter

See the output yourself here: http://www.ideone.com/16DpT

EDIT:

Of course, the above output explains only that temporary is bound to the function with const-parameter. It doesn't demonstrate life-extension. The following code demonstrates life-extension:

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!
}

Output:

A is constructed
const parameter
A is destructed

The fact that A is destructed after the function prints const parameter demonstrates that A's life is extended till the end of the called function!

Code at ideone : http://www.ideone.com/2ixA6

青瓷清茶倾城歌 2024-10-24 23:06:50

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

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

Use "C const & c" not "C & c"

Your temporary pair returned from make_pair cannot bind to the reference expected by your operator<<, only to a const reference.

长梦不多时 2024-10-24 23:06:50

但这确实有效:

#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;
}

我想这与名称解析有关。

This does work though:

#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;
}

I guess it has something to do with name resolution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文