Шаблон оператора << перегрузка и make_pair - PullRequest
2 голосов
/ 16 февраля 2011

У меня возникли проблемы с перегрузкой операторов элементами шаблона и использованием 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 ]

4 голосов
/ 16 февраля 2011

Параметр 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!
}

Выход:

параметр const

Смотрите сами вывод здесь: http://www.ideone.com/16DpT

EDIT:

Конечно, вышеприведенный вывод объясняет только то, что временная привязка связана с функцией с помощью 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 is destructed после того, как функция напечатает const parameter, демонстрирует, что жизнь А продлевается до конца вызванной функции!

Код на ideone: http://www.ideone.com/2ixA6

2 голосов
/ 16 февраля 2011

Используйте "C const & c", а не "C & c"

Ваша временная пара, возвращенная из make_pair, не может привязаться к ожидаемой вашим оператором ссылке <<, только к константной ссылке. </p>

0 голосов
/ 16 февраля 2011

Это работает, хотя:

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

Я думаю, это как-то связано с разрешением имени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...