【问题标题】:Template operator << overloading and make_pair模板运算符 << 重载和 make_pair
【发布时间】:2011-02-16 12:05:53
【问题描述】:

我在使用模板成员重载运算符和使用 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&lt;&lt; 有什么想法吗?

【问题讨论】:

    标签: c++ templates operator-overloading


    【解决方案1】:

    operator&lt;&lt;的参数应该是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

    编辑:

    当然,上面的输出只说明了临时绑定到具有 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被破坏了

    函数打印const parameter之后A is destructed的事实表明A的生命被延长到被调用函数的末尾!

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

    【讨论】:

    • 不确定这个基本原理是否非常有说服力,因为无论如何,临时值会一直持续到表达式结束(至少直到函数返回),并且不需要任何扩展。跨度>
    • 谢谢!我现在明白了这个问题。解决问题的另一种方法是通过复制传递 argumnet。
    【解决方案2】:

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

    从 make_pair 返回的临时对不能绑定到操作员期望的引用

    【讨论】:

      【解决方案3】:

      这确实有效:

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

      我猜这与名称解析有关。

      【讨论】:

      • 在 Visual Studio 上?但是 Visual Studio 允许其他编译器不允许的许多事情。我认为@ChAoS 正在尝试 linux。
      猜你喜欢
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 2015-09-15
      • 1970-01-01
      • 1970-01-01
      • 2022-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多