Как полезен tr1:: reference_wrapper?
Недавно я читал через Скотта Майерса отличный Эффективный С++. В одном из последних советов он рассмотрел некоторые функции из TR1 - я знал многих из них через Boost.
Однако был один, который я определенно НЕ распознал: tr1:: reference_wrapper.
Как и когда я буду использовать tr1:: reference_wrapper?
Ответы
Ответ 1
Мне нравится boost:: ref, насколько я знаю. В принципе, ссылка, которую можно скопировать. Очень полезно при привязке к функциям, где вам нужно передавать параметры по ссылке.
Например (с использованием синтаксиса boost):
void Increment( int& iValue )
{
iValue++;
}
int iVariable = 0;
boost::function< void () > fIncrementMyVariable = boost::bind( &Increment, boost::ref( iVariable ));
fIncrementMyVariable();
В этой статье доктора Доббса есть некоторая информация.
Надеюсь, это правильно и полезно.:)
Ответ 2
reference_wrapper<T>
- чрезвычайно полезная и простая библиотека. Внутренне reference_wrapper<T>
хранит указатель на T. Но интерфейс, который он предоставляет, не содержит никаких указателей.
- Позволяет ссылаться на другие простые объекты -
reference_wrapper<T>
может храниться в контейнере STL.
- Это помогает избежать ужасной нотации указателя - причины стольких ошибок сегментации. Замените указатель на T с помощью
reference_wrapper<T>
, указателей по ссылкам и T->f()
на T.f()
, где это возможно (указатели на курс необходимо сохранить для удаления выделенных кучей объектов, но для управления памятью Boost Pointer Containers весьма полезны).
Пример:
class A
{
//...
};
class B
{
public:
void setA(A& a)
{
a_ = boost::ref(a); // use boost::cref if using/storing const A&
}
A& getA()
{
return a_;
}
B(A& a): a_(a) {}
private:
boost::reference_wrapper<A> a_;
};
int main()
{
A a1;
B b(a1);
A a2;
b.setA(a2);
return 0;
}
Здесь я использовал ускоренную реализацию ссылочной оболочки, но стандарт С++ 0x тоже будет иметь ее. См. Также http://aszt.inf.elte.hu/~gsd/halado_cpp/ch11.html#Bind-ref