ткните носом
От: abrec Россия  
Дата: 02.10.09 11:26
Оценка:
Здравствуйте!

Может кто ткнет носом?

template< class TNumberHandler, typename T >
class CStreamNumberTypeImpl
{
protected:
    bool            m_bNeedSwap;
    T*        m_pValue;
    T        m_Value;
public:
    CStreamNumberTypeImpl()
        :m_bNeedSwap(true), m_pValue(NULL)
    {
    };

    void ToStream(std::ostream& s)
    {
        m_Value = *m_pValue;
        if(m_bNeedSwap)
        {
            TNumberHandler* pNumberHandler = static_cast< TNumberHandler* >(this);
            if(pNumberHandler) pNumberHandler->hton();
        }
        s.write(reinterpret_cast< char* >(&m_Value), sizeof(T));
    };
    void FromStream(std::istream& s)
    {
        s.read(reinterpret_cast< char* >(&m_Value), sizeof(T));
        if(m_bNeedSwap)
        {
            TNumberHandler* pNumberHandler = static_cast< TNumberHandler* >(this);
            if(pNumberHandler) pNumberHandler->ntoh();
        }
        *m_pValue = m_Value;
    };

    friend std::istream& operator >> (std::istream& s, CStreamNumberTypeImpl< TNumberHandler, T >& clLongTypeStream)
    {
        clLongTypeStream.FromStream(s);
        return s;
    };

    friend std::ostream& operator << (std::ostream& s, CStreamNumberTypeImpl< TNumberHandler, T >& clLongTypeStream)
    {
        clLongTypeStream.ToStream(s);
        return s;
    };
};

class CStreamSizeT :
    public CStreamNumberTypeImpl<CStreamSizeT, std::size_t>
{
public:
    CStreamSizeT(std::size_t* pValue, bool bNeedSwap = true)
    {
        m_pValue = pValue;
        m_bNeedSwap = bNeedSwap;
    };
    CStreamSizeT(const std::size_t* pValue, bool bNeedSwap = true)
    {
        m_pValue = const_cast< std::size_t* >(pValue);
        m_bNeedSwap = bNeedSwap;
    };
    void ntoh() { m_Value = static_cast< std::size_t >(ntohl(m_Value)); };
    void hton() { m_Value = static_cast< std::size_t >(htonl(m_Value)); };
};

//в коде

std::stringstream s;
std::size_t size(0);
....
s >> CStreamSizeT( &size, true ); //-->тут дает ошибку при компиляции под gcc в msvc все ок
Re: ткните носом
От: Alexander G Украина  
Дата: 02.10.09 12:08
Оценка: 3 (1)
Здравствуйте, abrec, Вы писали:

A>Здравствуйте!


A>Может кто ткнет носом?


A> friend std::istream& operator >> (std::istream& s, CStreamNumberTypeImpl< TNumberHandler, T >& clLongTypeStream)


A>s >> CStreamSizeT( &size, true ); //-->тут дает ошибку при компиляции под gcc в msvc все ок



http://rsdn.ru/forum/cpp/3509422.1.aspx
Автор: c-smile
Дата: 19.08.09
Русский военный корабль идёт ко дну!
Re: ткните носом
От: XuMuK Россия  
Дата: 02.10.09 12:18
Оценка: 3 (1) -1
Здравствуйте, abrec, Вы писали:

A>Здравствуйте!


A>//в коде


A>std::stringstream s;

A>std::size_t size(0);
A>CStreamSizeT non_const_object( &size, true );
A>s >> non_const_object;

A>[/ccode]


временные объекты в гцц константны, поэтому operator >>, ожидающий неконстантную ссылку не может быть вызван.
Re[2]: ткните носом
От: abrec Россия  
Дата: 02.10.09 12:21
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>http://rsdn.ru/forum/cpp/3509422.1.aspx
Автор: c-smile
Дата: 19.08.09


Спасибки. Я же эту нитку читал. Дырявая голова.
Re: ткните носом
От: AlexCrush Россия  
Дата: 02.10.09 12:31
Оценка: 3 (1)
Здравствуйте, abrec, Вы писали:

A>Здравствуйте!


A>Может кто ткнет носом?


нельзя передавать временный объект (CStreamSizeT) по неконстантной ссылке (operator >> (std::istream& s, CStreamNumberTypeImpl< TNumberHandler, T >& clLongTypeStream) ).
В студии работает, т.к. у них это разрешено. Но это не по стандарту.

В вашем случае, по-моему, проще всего добавить const к вышеозначенному параметру, а так же к методу FromStream.

З.Ы. А вообще, код странный. Как понимать это:

            TNumberHandler* pNumberHandler = static_cast< TNumberHandler* >(this);
            if(pNumberHandler) pNumberHandler->ntoh();

?
С dynamic_cast-ом попутали?
Re[2]: ткните носом
От: abrec Россия  
Дата: 02.10.09 12:36
Оценка:
Здравствуйте, AlexCrush, Вы писали:

AC>С dynamic_cast-ом попутали?

Да косячок
Re[2]: ткните носом
От: abrec Россия  
Дата: 02.10.09 12:41
Оценка:
Здравствуйте, AlexCrush, Вы писали:

AC>З.Ы. А вообще, код странный

странность только в этом?
AC>С dynamic_cast-ом попутали?
Re[3]: ткните носом
От: AlexCrush Россия  
Дата: 02.10.09 13:09
Оценка:
Здравствуйте, abrec, Вы писали:

A>странность только в этом?


Еще, если T будет не простым целочисленным типом, то сохранение через reinterpret_cast<char*>, sizeof(T)- опасно. А вдруг, там, в классе T, были указатели? Или stl контейнеры?
Или же это невозможно, by-design? Тогда наверное можно сильно уменьшить количество кода.
Re[4]: ткните носом
От: abrec Россия  
Дата: 02.10.09 13:12
Оценка:
Здравствуйте, AlexCrush, Вы писали:

AC>Еще, если T будет не простым целочисленным типом

простым
AC>by-design? Тогда наверное можно сильно уменьшить количество кода.
AC>Тогда наверное можно сильно уменьшить количество кода.
Буду признателен
Re[2]: ткните носом
От: Alexander G Украина  
Дата: 02.10.09 18:52
Оценка: 1 (1)
Здравствуйте, AlexCrush, Вы писали:

AC>
AC>            TNumberHandler* pNumberHandler = static_cast< TNumberHandler* >(this);
AC>            if(pNumberHandler) pNumberHandler->ntoh();
AC>

AC>?
AC>С dynamic_cast-ом попутали?

А зачем dynamic_cast здесь?
Русский военный корабль идёт ко дну!
Re[2]: ткните носом
От: Николай Ивченков  
Дата: 02.10.09 20:56
Оценка: +1
XuMuK:

XMK>временные объекты в гцц константны, поэтому operator >>, ожидающий неконстантную ссылку не может быть вызван.


Константность объекта и принадлежность выражения к rvalue — это две совершенно разные вещи. В данном случае объект неконстантный и на корректность инициализации ссылки влияет именно принадлежность инициализирующего выражения к rvalue. С lvalue-выражением такого же типа подобной проблемы бы не возникло — даже если бы оно обозначало временный объект.
Re[3]: ткните носом
От: wander  
Дата: 03.10.09 09:41
Оценка: 2 (1) +2
Здравствуйте, abrec, Вы писали:

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


AC>>С dynamic_cast-ом попутали?

A>Да косячок

Не нужен там dynamic_cast. Иногда бывает полезным такой трюк:

template <typename derived>
class base
{
public:
    // something...
protected:
    inline derived * self() { return static_cast<derived*>(this); }
};


Если параметром шаблона base всегда будет наследуемый от него класс ничего страшного не случится. главное функцией этой (self) в конструкторах и деструкторах не пользоваться
Re[3]: ткните носом
От: abrec Россия  
Дата: 05.10.09 06:59
Оценка:
Здравствуйте, Alexander G, Вы писали:

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


AG>А зачем dynamic_cast здесь?


Согласен. Поспешил. Он тут не нужен.
Re: ткните носом
От: Vamp Россия  
Дата: 06.10.09 17:31
Оценка:
На самом деле, почему бы temporary не-pod типов не быть lvalue — не очень понятно. Вероятно, авторы руководствовались той логикой, что какой смысл что-то изменять во временном объекте — он все равно сдохнет, но совершенно забыли о тоннах объектов с побочными эффектами. Простейший пример (хотя и не нужный в реальной жизни):


class AnyType {
...
    AnyType (int i) {...}
    AnyType operator++(int ) {...}
};

void dump_and_incr (AnyType& val) {
     cout << val;
     val++;
}

int i = 10;

dump_and_incr(i);
Да здравствует мыло душистое и веревка пушистая.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.