Имеется такой код:
template <class UnsignedInt, class OutIter>
OutIter print_unsinged(OutIter output, UnsignedInt in_int)
{
typedef typename std::iterator_traits<OutIter>::value_type char_t;
char_t tmp_chars[64];
int n = 0;
STATIC_ASSERT( UnsignedInt()-1 > 0, should_be_unsigned );
while (in_int)
{
//idiv... gcc/icc optimize it away, msvc does not.
tmp_chars[n++] = (char_t)('0' + in_int%10);
in_int = in_int/10;
}
while(n--)
*output++ = tmp_chars[n];
return output;
}
Когда использую его как
char buf[20];
*print_unsinged(buf, 0xFFFFFFFF) = '\0';
std::cout << buf;
то все в порядке, std::iterator_traits<OutIter>::value_type получается char.
но когда я использую его так
std::vector<char> str;
print_unsinged(std::back_inserter(str), 0xFFFFFFFF);
или так —
print_unsinged(std::ostream_iterator<char>(std::cout), 123U);
то возникает ошибка компиляции —
typename std::iterator_traits<OutIter>::value_type представляет собой void, и естесвенно ничего не работает.
можно конечно, указывать char_t как дополнительный параметр шаблонной функции, но хотелось бы без этого.
можно выкрутится?
и желательно, что бы на всех компиляторах без варнингов
если сделать просто typedef int char_t;
то получится —
test4.cpp(72) : warning C4244: 'argument' : conversion from 'char_t' to 'const char', possible loss of data
test4.cpp(99) : see reference to function template instantiation 'OutIter print_unsinged<unsigned int,std::ostream_iterator<_Ty>>(OutIter,UnsignedInt)' being compiled
with
[
OutIter=std::ostream_iterator<char>,
_Ty=char,
UnsignedInt=unsigned int
]
Здравствуйте, _Winnie, Вы писали:
_W>Имеется такой код:
_W>...
Вот простой способ, однако для всех итераторов с "плохим" value_type придется добавлять частичную специализацию it_traits:
template <class Iter>
struct it_traits
{
typedef typename std::iterator_traits<Iter>::value_type;
};
template <class Container>
struct it_traits<std::back_insert_iterator<Container> >
{
typedef typename Container::value_type value_type;
};
template <class CharType>
struct it_traits<std::ostream_iterator<CharType> >
{
typedef typename std::ostream_iterator<CharType>::char_type value_type;
};
template <class UnsignedInt, class OutIter>
OutIter print_unsinged(OutIter output, UnsignedInt in_int)
{
typedef typename it_traits<OutIter>::value_type char_t;
char_t tmp_chars[64];
int n = 0;
STATIC_ASSERT( UnsignedInt()-1 > 0, should_be_unsigned );
while (in_int)
{
//idiv... gcc/icc optimize it away, msvc does not.
tmp_chars[n++] = (char_t)('0' + in_int%10);
in_int = in_int/10;
}
while(n--)
*output++ = tmp_chars[n];
return output;
}
int main(int argc, _TCHAR* argv[])
{
std::vector<char> vec;
print_unsinged(std::back_inserter(vec), 0xFFFF);
std::copy(vec.begin(), vec.end(), std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
print_unsinged(std::ostream_iterator<char>(std::cout), 0xFFFFF);
return 0;
}
_Winnie wrote:
> Имеется такой код:
>
> > template <class UnsignedInt, class OutIter>
> OutIter print_unsinged(OutIter output, UnsignedInt in_int)
> {
> typedef typename std::iterator_traits<OutIter>::value_type char_t;
> char_t tmp_chars[64];
> int n = 0;
> STATIC_ASSERT( UnsignedInt()-1 > 0, should_be_unsigned );
>
> while (in_int)
> {
> //idiv... gcc/icc optimize it away, msvc does not.
> tmp_chars[n++] = (char_t)('0' + in_int%10);
> in_int = in_int/10;
> }
>
> while(n--)
> *output++ = tmp_chars[n];
>
> return output;
> }
>
Предлагаю в качестве буфера всегда использовать char. Здесь ты используешь только ASCII символы 0-9, которые во многих кодировках (и во всех юникодах) имеют те же самые коды, что и ASCII.
--
Maxim YegorushkinPosted via RSDN NNTP Server 1.9