В моем проекте я хочу разделить поток на некоторый заданный тип значений, поэтому я реализую функцию шаблона как
template <typename TElem, typename TOutputIter>
TOutputIter SplitSpace(std::istream& IS, TOutputIter result)
{
TElem elem;
while (IS >> elem)
{
*result = elem;
++result;
}
return result;
}
Я думаю, что это неудобно, так как я должен явно указывать тип TElem
при вызове. Например, я должен написать:
std::vector<int> v;
SplitSpace<int>(std::cin, back_inserter(v));
// I want to it to be SplitSpace(std::cin, back_inserter(v));
Я попытался получить тип значения из итератора (шаблона) и использовал std::iterator_traits
следующим образом:
template <typename TOutputIter>
TOutputIter SplitSpace(std::istream& IS, TOutputIter result)
{
typename std::iterator_traits<TOutputIter>::value_type elem;
while (IS >> elem)
{
*result = elem;
++result;
}
return result;
}
Однако приведенные выше коды не работают для back_insert_iterator
. Я проверил исходные коды back_insert_iterator/front_insert_iterator/insert_iterator
в пространстве имен std
и нашел, что value_type/difference_type/pointer/reference
- все void
.
Я хотел бы знать, почему все эти типы void
, есть ли какое-либо соображение для этого? Другой вопрос: возможно ли реализовать функцию SplitSpace
без явного указания типа элемента при вызове? Спасибо.