При использовании СТЛ контейнеры вместе с reference_wrappers типов стручок кода, такие как следующие прекрасно работает:Контейнеры reference_wrappers (требуется операторы сравнения?)
int i = 0;
std::vector< boost::reference_wrapper<int> > is;
is.push_back(boost::ref(i));
std::cout << (std::find(is.begin(),is.end(),i)!=is.end()) << std::endl;
Однако, если вы используете не-POD типов, таких как (надуманный пример):
struct Integer
{
int value;
bool operator==(const Integer& rhs) const
{
return value==rhs.value;
}
bool operator!=(const Integer& rhs) const
{
return !(*this == rhs);
}
};
Это не достаточно, чтобы объявить операторы сравнения выше, Aditionally вы должны объявить:
bool operator==(const boost::reference_wrapper<Integer>& lhs, const Integer& rhs)
{
return boost::unwrap_ref(lhs)==rhs;
}
И, возможно, также:
bool operator==(const Integer& lhs, const boost::reference_wrapper<Integer>& rhs)
{
return lhs==boost::unwrap_ref(rhs);
}
Для того, чтобы получить эквивалентный код для работы:
Integer j = { 0 };
std::vector< boost::reference_wrapper<Integer> > js;
js.push_back(boost::ref(j));
std::cout << (std::find(js.begin(),js.end(),j)!=js.end()) << std::endl;
Теперь мне интересно, если это действительно так, это означало бы сделать, так как это несколько непрактично. Просто кажется, что должно быть более простое решение, например. Шаблоны:
template<class T>
bool operator==(const boost::reference_wrapper<T>& lhs, const T& rhs)
{
return boost::unwrap_ref(lhs)==rhs;
}
template<class T>
bool operator==(const T& lhs, const boost::reference_wrapper<T>& rhs)
{
return lhs==boost::unwrap_ref(rhs);
}
Там, наверное, хорошая причина, почему reference_wrapper ведет себя так, как это делает (возможно, для размещения типов без POD без операторов сравнения?). Может быть, уже есть изящное решение, и я просто его не нашел.
Предпочитают функции нечлена для функций-членов. Такая ситуация является одной из причин. Когда это функция-член, оператор * требует * левая сторона - это определенный тип. Напротив, когда это бесплатная функция, она может быть вызвана на любые типы, конвертируемые в аргументы, которые являются «reference_wrapper». – GManNickG
@GMan: Конечно, это имеет смысл, спасибо за объяснение! – kloffy