Рассмотрим этот код:
struct CData
{
int bar() { return 1; }
};
int main()
{
typedef boost::numeric::ublas::vector<CData> vec_data_t;
vec_data_t foo;
for (vec_data_t::iterator it = foo.begin();
it != foo.end();
++it)
{
std::cout << it->bar() << std::endl; // COMPILE ERROR!
std::cout << (*it).bar() << std::endl; // ok
}
return 0;
}
Почему первая строка в цикле с использованием оператора стрелки не компилируется, а следующая строка с использованием оператора * работает нормально?
Я привык использовать оператор стрелки с итераторами контейнера std и удивляюсь, почему он не работает с итераторами boost :: numeric :: ublas.
Я использую Boost 1.54 и GCC 4.9.1 и точное сообщение об ошибке:
error: base operand of ‘->’ has non-pointer type ‘boost::numeric::ublas::vector<CData>::iterator’
Я бы сказал, что это ошибка в Boost. Согласно документации, boost::numeric::ublas::vector
модели Векторное выражение, который обеспечивает Индексируемый двунаправленный итератор, который (среди прочего) перечисляет следующее как допустимое выражение и его семантику:
Доступ участника |
it->m
| Требования к типуT
это тип для которогоt.m
определено.
Доступ участника |
it->m
| непременное условиеit
разыменовывается | Семантика Эквивалентно(*it).m
Изучение кода показывает, что indexed_iterator
шаблон класса не определяет operator->
, Согласно документам, это должно быть ясно.
Возможно, вы захотите поискать отчет об ошибке и, если его нет, подайте один.
Так как operator->()
является чрезвычайно сложным оператором для реализации права.
Любой нетривиальный пользовательский итератор, который я когда-либо видел, не реализует ->
,
Я предполагаю, что разработчики uBlas не знали, как это сделать (и я их не виню).
Проблема, конечно, заключается в том, чтобы гарантировать, что в конце ->
цепь, и вдобавок к этому для it->bla
иметь то же значение, что и (*it).bla