Универсальная перегрузка operator<<
От: Андрей Е  
Дата: 04.08.11 09:50
Оценка:
Хочется перегрузить оператор вывода в поток для своего класса operator<< так, чтобы он мог выводить в произвольный поток типа std::basic_ostream, а не только в std::ostream.


Допустим у на есть такой класс:
struct Vector2D
{
  float x;
  float y;
}


Возможный вариант перегрузки оператора:
template<typename C>
std::basic_ostream<C>& operator<<(std::basic_ostream<C>& ostr, const Vector2D& point)
{
    ostr << "( ";
    ostr << point.x;
    ostr << ", ";
    ostr << point.y;
    ostr << " )";
    return ostr;
}

К сожалению этот вариант работает только при C = char. При других значениях C(например wchar_t) строковые литералы выводятся как целое число. При этом float чудесным образом выводится правильно.

Вопрос: что это за чудесный способ, который позволяет float выводиться в поток правильно при произвольном C? И можно ли как-то этот чудесный способ использовать для вывода строковых литералов?
Re: Универсальная перегрузка operator<<
От: _nn_ www.nemerleweb.com
Дата: 04.08.11 09:56
Оценка:
Здравствуйте, Андрей Е, Вы писали:

АЕ>Вопрос: что это за чудесный способ, который позволяет float выводиться в поток правильно при произвольном C? И можно ли как-то этот чудесный способ использовать для вывода строковых литералов?


А вы как проверяли ?

GCC , MSVC говорят что все работает:
http://ideone.com/jOU2d
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Универсальная перегрузка operator<<
От: zaufi Земля  
Дата: 04.08.11 10:37
Оценка:
Здравствуйте, Андрей Е, Вы писали:


для начала basic_stream это шаблон с 2мя параметрами
АЕ>
АЕ>template<typename CharT, typename Traits>
АЕ>std::basic_ostream<C>& operator<<(std::basic_ostream<CharT, Traits>& ostr, const Vector2D& point)
АЕ>{
АЕ>    ostr << "( ";
АЕ>    ostr << point.x;
АЕ>    ostr << ", ";
АЕ>    ostr << point.y;
АЕ>    ostr << " )";
АЕ>    return ostr;
АЕ>}
АЕ>

а во вторых, в зависимости от CharT строковые литералы должны быть без (char) или с (wchar_t) префиксом L. то что у тебя вообще что-то печаталось это просто случайность...
Re[2]: Универсальная перегрузка operator<<
От: Masterkent  
Дата: 04.08.11 11:05
Оценка:
zaufi:

Z>а во вторых, в зависимости от CharT строковые литералы должны быть без (char) или с (wchar_t) префиксом L.


В случае wchar_t всё должно нормально работать и с L, и без него.

C++03 — 27.6.2.1:
template<class charT, class traits>
  basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&,
                                          const charT*);
template<class charT, class traits>
  basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&,
                                          const char*);
Re: Универсальная перегрузка operator<<
От: srmxx  
Дата: 04.08.11 11:33
Оценка:
class pnt
{
private:
    int m_x, m_y;

public:
    pnt(int x, int y) : m_x(x), m_y(y)
    {
    }

    int get_x() const
    {
        return m_x;
    }

    int get_y() const
    {
        return m_y;
    }
};

template <class S>
S& operator << (S& s, pnt const& p)
{
    s << "(" << p.get_x() << ", " << p.get_y() << ")";
    return s;
}

int main()
{
    pnt p(1, 2);
    std::cout << p << std::endl;
    std::wcout << p << std::endl;
}
Re[2]: Универсальная перегрузка operator<<
От: zaufi Земля  
Дата: 04.08.11 13:54
Оценка:
Здравствуйте, srmxx, Вы писали:

S>
<SKIP>
S>int main()
S>{
S>    pnt p(1, 2);
S>    std::cout << p << std::endl;
S>    std::wcout << p << std::endl;
S>}
S>


а так должно работать? да поправят меня знатоки стандарта, давно где-то прочитал, что так делать нельзя... (в стандарт лезть не досуг %)
Re[3]: Универсальная перегрузка operator<<
От: srmxx  
Дата: 04.08.11 14:03
Оценка:
Здравствуйте, zaufi, Вы писали:

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


S>>
Z><SKIP>
S>>int main()
S>>{
S>>    pnt p(1, 2);
S>>    std::cout << p << std::endl;
S>>    std::wcout << p << std::endl;
S>>}
S>>


Z>а так должно работать? да поправят меня знатоки стандарта, давно где-то прочитал, что так делать нельзя... (в стандарт лезть не досуг %)


А в чём, по вашему, проблема? У меня скомпилилось и заработало так, как и должно. Хотя, может от компилятора зависит.
Re[4]: Универсальная перегрузка operator<<
От: zaufi Земля  
Дата: 04.08.11 14:07
Оценка:
Здравствуйте, srmxx, Вы писали:

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


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


S>>>
Z>><SKIP>
S>>>int main()
S>>>{
S>>>    pnt p(1, 2);
S>>>    std::cout << p << std::endl;
S>>>    std::wcout << p << std::endl;
S>>>}
S>>>


Z>>а так должно работать? да поправят меня знатоки стандарта, давно где-то прочитал, что так делать нельзя... (в стандарт лезть не досуг %)


S>А в чём, по вашему, проблема? У меня скомпилилось и заработало так, как и должно. Хотя, может от компилятора зависит.


может....
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27569
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.