помогите вывести тип
От: MuTPu4  
Дата: 23.11.05 20:18
Оценка:
Заранее извиняюсь за большой пример, это просто чтобы контекст задачи был понятен:

#include <vector>

template< typename container_t >
class my_back_insert_iterator
{
  public:

    my_back_insert_iterator( void )
    {}

    explicit
    my_back_insert_iterator( container_t & )
    {}
};

class empty_back_inserter
{
  public:

    template< typename container_t >
    operator my_back_insert_iterator< container_t >( )    //(1)
    {
      return( my_back_insert_iterator< container_t >( ) );
    }
};

template< typename container_t >
inline my_back_insert_iterator< container_t >
back_inserter( container_t & container )
{
  return( my_back_insert_iterator< container_t >( container ) );
}

inline empty_back_inserter
back_inserter( void )
{
  return( empty_back_inserter( ) );
}


//--------------------------------------------------------------------------------------

void call1( 
    my_back_insert_iterator< ::std::vector< int > > 
  , my_back_insert_iterator< ::std::vector< int > > 
);

template< typename iter_t >
void call2( iter_t , iter_t );

int main( void )
{
  //для нешаблонной функции работает оператор приведения (1)
  call1( back_inserter( ::std::vector< int >( ) ), back_inserter( ) );
    
  //а для шаблонной до него дело не доходит, т.к. невозможно определиться с типом параметров
  //очень бы хотелось такого синтаксиса:
  call2( back_inserter( ::std::vector< int >( ) ), back_inserter( ) ); //error
}


Пока приходится писать back_inserter< ::std::vector< int > >( ), но это крайне неудобно
Можно ли тут что-нибудь придумать?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: помогите вывести тип
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 24.11.05 00:21
Оценка: 2 (1)
Здравствуйте, MuTPu4, Вы писали:

MTP>Пока приходится писать back_inserter< ::std::vector< int > >( ), но это крайне неудобно

MTP>Можно ли тут что-нибудь придумать?

Если есть возможность, добавить такое определение функции call2:
template< typename iter_t, typename iter2_t>
void call2(iter_t B, iter2_t E)
{
  call2(B, iter_t(E));
}

Или заменить существующий вариант этой функции.

PS. Возможно, использование дипазона итераторов, таких как Boost.Range, в алгоритмах вместо итераторов, избавит от подобных проблем. Правда, появятся новые.
getboost.codeplex.com
citylizard.codeplex.com
Re: помогите вывести тип
От: _Dreamer Россия  
Дата: 24.11.05 03:15
Оценка:
Здравствуйте, MuTPu4, Вы писали:

MTP>template< typename iter_t >

MTP>void call2( iter_t , iter_t );

MTP>int main( void )

MTP>{
MTP> //очень бы хотелось такого синтаксиса:
MTP> call2( back_inserter( ::std::vector< int >( ) ), back_inserter( ) ); //error
MTP>}
MTP>[/ccode]

MTP>Пока приходится писать back_inserter< ::std::vector< int > >( ), но это крайне неудобно

MTP>Можно ли тут что-нибудь придумать?

Тоесть будут частыми случаи, когда второй параметр call2 — это именно back_inserter( ), который в конечном итоге становится my_back_insert_iterator< container_t >() ? может тогда так написать —
template< typename iter_t >
void call2( iter_t , iter_t = iter_t() );

ну и получится так —
int main( void )
{
  call2( back_inserter( ::std::vector< int >( ) ) ); 
}
2 all
От: MuTPu4  
Дата: 24.11.05 10:40
Оценка:
Спасибо за ответы. Но проблема остается. Наверное, я не достаточно точно задал вопрос. Дело в том, что в рамках моей задачи я не могу менять сигнатуры/декларации функций, т.к. существует множество функций, принимающих именно итераторный интервал (например, стандартные алгоритмы). Зато можно менять класс my_back_insert_iterator и вспомогательные функции.
Собственно, возвращаемое значение back_inserter( ) без параметров не несет никакой полезной информации, единственное что мне нужно от него — чтобы осуществлялся вызов функции и чтобы потом я мог отличить его от других значений итератора, пусть даже у него будет другой тип.
Хотелось бы как-то извратится с шаблонами и приведениями типов, чтобы сделать возможным удобный синтаксис (run-time полиморфизм не предлагать )
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: 2 all
От: srggal Украина  
Дата: 24.11.05 10:49
Оценка:
Здравствуйте, MuTPu4, Вы писали:

MTP>Собственно, возвращаемое значение back_inserter( ) без параметров не несет никакой полезной информации, единственное что мне нужно от него — чтобы осуществлялся вызов функции и чтобы потом я мог отличить его от других значений итератора, пусть даже у него будет другой тип.

MTP>Хотелось бы как-то извратится с шаблонами и приведениями типов, чтобы сделать возможным удобный синтаксис (run-time полиморфизм не предлагать )

Отличть в compile Or runtime?
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[2]: 2 all
От: MuTPu4  
Дата: 24.11.05 12:17
Оценка:
Здравствуйте, srggal, Вы писали:

S>Здравствуйте, MuTPu4, Вы писали:


MTP>>Собственно, возвращаемое значение back_inserter( ) без параметров не несет никакой полезной информации, единственное что мне нужно от него — чтобы осуществлялся вызов функции и чтобы потом я мог отличить его от других значений итератора, пусть даже у него будет другой тип.


S>Отличть в compile Or runtime?


Достаточно run-time. Например, сейчас у меня back_inserter< container_t >( ) без параметров возвращает тот же тип my_back_insert_iterator, который я отличаю в run-time по приветному полю данных. Если тип пустого итератора будет отличатся, то я просто добавлю шаблонный метод сравнения в my_back_insert_iterator. Так что можно и так и так, главное чтобы вызывались итераторные алгоритмы, а дальше я уже отличу .
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: 2 all
От: srggal Украина  
Дата: 24.11.05 12:32
Оценка:
Здравствуйте, MuTPu4, Вы писали:


ГМ, подумалось:

Вы уверены, что правильносформулировали свою задачу ?

Как много вы можете назвать алгоритмов STL которым передуются 2 OutputIterator ?

Быть может если Вы переформулируете задачу, то если и найдется прямое решение, то посоветуют обходное ?
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[4]: 2 all
От: MuTPu4  
Дата: 24.11.05 13:28
Оценка:
Здравствуйте, srggal, Вы писали:

S>Вы уверены, что правильносформулировали свою задачу ?


S>Как много вы можете назвать алгоритмов STL которым передуются 2 OutputIterator ?

Да, вы правы. Ляпнул не подумав Стандартная библиотека исключается. Вообще, с 2-мя OutputIterator-ами, естественно, ничего не получиться, поэтому my_back_insert_iterator относится к my_extensible_iterator_tag .

S>Быть может если Вы переформулируете задачу, то если и найдется прямое решение, то посоветуют обходное ?

Задача примерно такая. Я планирую написать итератор (предположительно bidirectional), который бы автоматически расширялся при необходимости. Т.е., например, я хочу сделать безопасную версию copy с проверкой переполнения и поэтому передаю ей интервал forward-итераторов, а в том случае, если возможно расширение контейнра хочу использовать тот же алгоритм, но с моим итераторным адаптором:

copy( in_ptr, in_ptr + 10, out_ptr, out_ptr + max_size ); //может скопироваться не все, но не выходит за пределы массива
copy( in_ptr, in_ptr + 10, back_extender( my_vector ), back_extender( ) ); //всегда удачно, использую тот же алгоритм
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: помогите вывести тип
От: MuTPu4  
Дата: 27.11.05 19:19
Оценка:
Может кто еще не видел

У меня пока только такие идеи.
Либо использовать злой макрос в стиле Для ленивых
Автор: remark
Дата: 26.11.05
. Но я, конечно, на такое не пойду . Либо передавать фиктивный параметр для пустого итератора.
Но, с другой стороны, я уже почти созрел на переписывание алгоритмов с использованием boost.range, это решит проблему . Кто-нибудь реально пишет/использует алгоритмы в таком стиле? Я пока видел из серьезных проектов только в Adobe Source Libraries. Есть ли шанс интеграции range в стандарт в ближайшее время?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: помогите вывести тип
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 27.11.05 23:48
Оценка: 1 (1)
Здравствуйте, MuTPu4, Вы писали:

MTP>Может кто еще не видел


MTP>Но, с другой стороны, я уже почти созрел на переписывание алгоритмов с использованием boost.range, это решит проблему . Кто-нибудь реально пишет/использует алгоритмы в таком стиле?


Я . Правда, использую свой, так как Boost.Range еще сыроват и багов там хватает. Например:

VC 7.1 ошибка компиляции.
А этот посерьезнее.
getboost.codeplex.com
citylizard.codeplex.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.