2010-04-09 2 views
1

При использовании СТЛ контейнеры вместе с 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 без операторов сравнения?). Может быть, уже есть изящное решение, и я просто его не нашел.

+1

Предпочитают функции нечлена для функций-членов. Такая ситуация является одной из причин. Когда это функция-член, оператор * требует * левая сторона - это определенный тип. Напротив, когда это бесплатная функция, она может быть вызвана на любые типы, конвертируемые в аргументы, которые являются «reference_wrapper». – GManNickG

+0

@GMan: Конечно, это имеет смысл, спасибо за объяснение! – kloffy

ответ

2

ли приведенный выше пример работы, когда вы объявляете оригинальные процедуры сравнения, как, например:

friend bool operator==(const Integer& lhs, const Integer& rhs) 
{ 
    return lhs.value == rhs.value; 
} 

friend bool operator!=(const Integer& lhs, const Integer& rhs) 
{ 
    return !(lhs == rhs); 
} 

Обратите внимание, что объявление сравнительной рутины друга в классе не то же самое, как объявить сравнения обычной функции-члена, которое почему они могут работать, пока ваш исходный код не может.

+0

Действительно, спасибо, спасибо! У меня было ощущение, что ответ будет поразительно простым. – kloffy

 Смежные вопросы

  • Нет связанных вопросов^_^