портирование кода с MSVC на gcc
От: abrec Россия  
Дата: 19.08.09 15:33
Оценка:
Здравствуйте!
Писал проект на MSVC с галочкой в мозге, что возможно надо будет портировать на linux. Сбылось.
Поставил openSUSE 11, codeblocks, boost_1_39_0.
Началось.... Нашел у себя несколько явных косяков
Помогите разобраться.
class CINIItem
{
private:
    std::string m_strSectionName;
    std::string m_strValueName;
    std::string m_strValue;
public:
    CINIItem(const char* pszSectionName, const char* pszValueName,    const char* pszValue);
    ...
    const std::string& GetValue()const { return m_strValue; } ;
    void SetValue(const std::string& strNewValue) { m_strValue = strNewValue; };
        ...
    typedef std::set< CINIItem, CINIItem::Less > INIITEMS;
};
class CINIData
{
protected:
    CINIItem::INIITEMS m_INIItems;
public:
    CINIData(){};
        ...
    bool SetValue(const char* pszSectionName, const char* pszValueName, const long& lValue)
    {
        CINIItem item(pszSectionName, pszValueName, "");
        CINIItem::INIITEMS::iterator iter = m_INIItems.find(item);
        if(iter == m_INIItems.end()) return false;
        std::stringstream sValue;
        sValue << lValue;
        (*iter).SetValue(sValue.str());//здесь ошибка!!!!
//../Public/Include/inidata.h|165|ошибка: нет подходящей функции для вызова ‘CINIItem::SetValue(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) const’|
//../Public/Include/inidata.h|50|замечание: претенденты: void CINIItem::SetValue(const std::string&) <near match>|
        return true;
    };
        ...
};
Re: портирование кода с MSVC на gcc
От: Аноним  
Дата: 19.08.09 15:45
Оценка:
std::ostringstream ?
Re[2]: портирование кода с MSVC на gcc
От: abrec Россия  
Дата: 19.08.09 15:49
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>std::ostringstream ?


не понял. но не помогло.
Re[3]: портирование кода с MSVC на gcc
От: Аноним  
Дата: 19.08.09 15:52
Оценка:
#include <sstream>

class CINIItem
{
private:
    std::string m_strSectionName;
    std::string m_strValueName;
    std::string m_strValue;
public:
    CINIItem(const char* pszSectionName, const char* pszValueName,    const char* pszValue);
    ...
    const std::string& GetValue()const { return m_strValue; } ;
    void SetValue(const std::string& strNewValue) { m_strValue = strNewValue; };
        ...
    typedef std::set< CINIItem, CINIItem::Less > INIITEMS;
};
class CINIData
{
protected:
    CINIItem::INIITEMS m_INIItems;
public:
    CINIData(){};
        ...
    bool SetValue(const char* pszSectionName, const char* pszValueName, const long& lValue)
    {
        CINIItem item(pszSectionName, pszValueName, "");
        CINIItem::INIITEMS::iterator iter = m_INIItems.find(item);
        if(iter == m_INIItems.end()) return false;
//        std::stringstream sValue;
        std::ostringstream sValue;
        sValue << lValue;
        (*iter).SetValue(sValue.str());
        return true;
    };
        ...
};
Re[4]: портирование кода с MSVC на gcc
От: abrec Россия  
Дата: 19.08.09 15:53
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>#include <sstream>

А>class CINIItem
А>{
А>private:
А>    std::string m_strSectionName;
А>    std::string m_strValueName;
А>    std::string m_strValue;
А>public:
А>    CINIItem(const char* pszSectionName, const char* pszValueName,    const char* pszValue);
А>    ...
А>    const std::string& GetValue()const { return m_strValue; } ;
А>    void SetValue(const std::string& strNewValue) { m_strValue = strNewValue; };
А>        ...
А>    typedef std::set< CINIItem, CINIItem::Less > INIITEMS;
А>};
А>class CINIData
А>{
А>protected:
А>    CINIItem::INIITEMS m_INIItems;
А>public:
А>    CINIData(){};
А>        ...
А>    bool SetValue(const char* pszSectionName, const char* pszValueName, const long& lValue)
А>    {
А>        CINIItem item(pszSectionName, pszValueName, "");
А>        CINIItem::INIITEMS::iterator iter = m_INIItems.find(item);
А>        if(iter == m_INIItems.end()) return false;
А>//        std::stringstream sValue;
А>        std::ostringstream sValue;
А>        sValue << lValue;
А>        (*iter).SetValue(sValue.str());
А>        return true;
А>    };
А>        ...
А>};
не не не не помогло :)
А>
Re[5]: портирование кода с MSVC на gcc
От: Аноним  
Дата: 19.08.09 15:57
Оценка:
че? !!!!0 == true сообщения об ошибках покажи
Re[6]: портирование кода с MSVC на gcc
От: abrec Россия  
Дата: 19.08.09 15:59
Оценка:
Здравствуйте, Аноним, Вы писали:

А>че? !!!!0 == true сообщения об ошибках покажи


//../Public/Include/inidata.h|165|ошибка: нет подходящей функции для вызова ‘CINIItem::SetValue(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) const’|
//../Public/Include/inidata.h|50|замечание: претенденты: void CINIItem::SetValue(const std::string&) <near match>|
Re: портирование кода с MSVC на gcc
От: Sergey Россия  
Дата: 19.08.09 15:59
Оценка: 2 (1) +1
Здравствуйте, abrec, Вы писали:

A>Писал проект на MSVC с галочкой в мозге, что возможно надо будет портировать на linux. Сбылось.

A>Поставил openSUSE 11, codeblocks, boost_1_39_0.
A>Началось.... Нашел у себя несколько явных косяков
A>Помогите разобраться.
A>
A>//../Public/Include/inidata.h|165|ошибка: нет подходящей функции для вызова ‘CINIItem::SetValue(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) const’|
A>//../Public/Include/inidata.h|50|замечание: претенденты: void CINIItem::SetValue(const std::string&) <near match>|
A>


Ну написано же — константность мешает. Почему VC разрешает изменять элемент множества через итератор и что при этом происходит с множеством и с итератором — хз.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[2]: портирование кода с MSVC на gcc
От: abrec Россия  
Дата: 19.08.09 16:00
Оценка:
Здравствуйте, Sergey, Вы писали:

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


A>>Писал проект на MSVC с галочкой в мозге, что возможно надо будет портировать на linux. Сбылось.

A>>Поставил openSUSE 11, codeblocks, boost_1_39_0.
A>>Началось.... Нашел у себя несколько явных косяков
A>>Помогите разобраться.
A>>
A>>//../Public/Include/inidata.h|165|ошибка: нет подходящей функции для вызова ‘CINIItem::SetValue(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) const’|
A>>//../Public/Include/inidata.h|50|замечание: претенденты: void CINIItem::SetValue(const std::string&) <near match>|
A>>


S>Ну написано же — константность мешает. Почему VC разрешает изменять элемент множества через итератор и что при этом происходит с множеством и с итератором — хз.


так вроде есть отдельный const_iterator.???
Re: портирование кода с MSVC на gcc
От: Sni4ok  
Дата: 19.08.09 16:02
Оценка:
Здравствуйте, abrec, Вы писали:

бага msvc- что скомпилила, по итератеру сета нельзя менять значение, ибо сет может стать невалидным.
Re[2]: портирование кода с MSVC на gcc
От: abrec Россия  
Дата: 19.08.09 16:03
Оценка:
Здравствуйте, Sni4ok, Вы писали:

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


S>бага msvc- что скомпилила, по итератеру сета нельзя менять значение, ибо сет может стать невалидным.


тобишь надо взять элемент изменить и обратно в сет засунуть?
Re[3]: портирование кода с MSVC на gcc
От: Sni4ok  
Дата: 19.08.09 16:04
Оценка: 3 (1)
Здравствуйте, abrec, Вы писали:

A>так вроде есть отдельный const_iterator.???


константый итератор нельзя удалить, неконстантный можно, чтобы поменять значение в set'е- сначала удалите по итератеру, и потом добавте новое значение.
Re[6]: портирование кода с MSVC на gcc
От: Аноним  
Дата: 19.08.09 16:05
Оценка:
!!!!true == true
Re[4]: портирование кода с MSVC на gcc
От: abrec Россия  
Дата: 19.08.09 16:06
Оценка:
Здравствуйте, Sni4ok, Вы писали:

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


A>>так вроде есть отдельный const_iterator.???


S>константый итератор нельзя удалить, неконстантный можно, чтобы поменять значение в set'е- сначала удалите по итератеру, и потом добавте новое значение.


в принципе логично. ведь он там пересортировывается постоянно. как же vc пропустила?
Re: портирование кода с MSVC на gcc
От: Юрий Жмеренецкий ICQ 380412032
Дата: 19.08.09 16:06
Оценка: 67 (3)
Здравствуйте, abrec, Вы писали:

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

A>Писал проект на MSVC с галочкой в мозге, что возможно надо будет портировать на linux. Сбылось.
A>Поставил openSUSE 11, codeblocks, boost_1_39_0.
A>Началось.... Нашел у себя несколько явных косяков
A>Помогите разобраться.
A>
A>class CINIItem
A>{
A>private:
A>    std::string m_strSectionName;
A>    std::string m_strValueName;
A>    std::string m_strValue;
A>public:
A>    CINIItem(const char* pszSectionName, const char* pszValueName,    const char* pszValue);
A>    ...
A>    const std::string& GetValue()const { return m_strValue; } ;
A>    void SetValue(const std::string& strNewValue) { m_strValue = strNewValue; };
A>        ...
A>    typedef std::set< CINIItem, CINIItem::Less > INIITEMS;
A>};
A>class CINIData
A>{
A>protected:
A>    CINIItem::INIITEMS m_INIItems;
A>public:
A>    CINIData(){};
A>        ...
A>    bool SetValue(const char* pszSectionName, const char* pszValueName, const long& lValue)
A>    {
A>        CINIItem item(pszSectionName, pszValueName, "");
A>        CINIItem::INIITEMS::iterator iter = m_INIItems.find(item);
A>        if(iter == m_INIItems.end()) return false;
A>        std::stringstream sValue;
A>        sValue << lValue;
A>        (*iter).SetValue(sValue.str());//здесь ошибка!!!!
A>//../Public/Include/inidata.h|165|ошибка: нет подходящей функции для вызова ‘CINIItem::SetValue(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) const’|
A>//../Public/Include/inidata.h|50|замечание: претенденты: void CINIItem::SetValue(const std::string&) <near match>|
A>        return true;
A>    };
A>        ...
A>};
A>


Это "правильная" ошибка, в MSVC баг связанный с багом в стандарте: разрешено вызвать неконстантные методы для результата разыменования итераторов std::set, хотя по логике ключи иммутабельны. Для изменения значения ключа нужно удалить элемент со старым значением и вставить с измененным.
Re[3]: портирование кода с MSVC на gcc
От: Sni4ok  
Дата: 19.08.09 16:09
Оценка: 2 (1)
Здравствуйте, abrec, Вы писали:

A>тобишь надо взять элемент изменить и обратно в сет засунуть?


угу, но если вы уверены, что ваша неконстантная операция не может повлиять на сортировку(не изменяете полей от которых зависит компаратор), то лучше воспользоваться конст-кастом, поскольку удаление и обратная вставка- всётаки не дешёвая операция.
Re[4]: портирование кода с MSVC на gcc
От: abrec Россия  
Дата: 19.08.09 16:15
Оценка:
Здравствуйте, Sni4ok, Вы писали:

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


A>>тобишь надо взять элемент изменить и обратно в сет засунуть?


S>угу, но если вы уверены, что ваша неконстантная операция не может повлиять на сортировку(не изменяете полей от которых зависит компаратор), то лучше воспользоваться конст-кастом, поскольку удаление и обратная вставка- всётаки не дешёвая операция.

спасибо const_cast ом вышел из ситуевины.
1. барьер пройден
Re[7]: портирование кода с MSVC на gcc
От: Аноним  
Дата: 19.08.09 16:16
Оценка:
извини, я разглядел наконец, что компилятор к другому совсем цеплялся.
Re[2]: портирование кода с MSVC на gcc
От: Кодт Россия  
Дата: 19.08.09 17:03
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Это "правильная" ошибка, в MSVC баг связанный с багом в стандарте: разрешено вызвать неконстантные методы для результата разыменования итераторов std::set, хотя по логике ключи иммутабельны. Для изменения значения ключа нужно удалить элемент со старым значением и вставить с измененным.


То есть, value_type — не typedef const key_type, а просто key_type ?!
(По аналогии с map — typedef pair<const key_type,mapped_type> value_type)

Полез в Стандарт изумляться...
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[5]: портирование кода с MSVC на gcc
От: Кодт Россия  
Дата: 19.08.09 17:03
Оценка: 3 (1)
Здравствуйте, abrec, Вы писали:

S>>угу, но если вы уверены, что ваша неконстантная операция не может повлиять на сортировку(не изменяете полей от которых зависит компаратор), то лучше воспользоваться конст-кастом, поскольку удаление и обратная вставка- всётаки не дешёвая операция.

A>спасибо const_cast ом вышел из ситуевины.
A>1. барьер пройден

Может, хотя бы проверку делать?
template<class Set>
void set_update(Set& cont, Set::iterator it, Set::value_type value)
{
    Set::value_compare cmp = cont.value_comp();
    if(!cmp(*it,value) && !cmp(value,*it)) // value == *it
        return;

    Set::iterator left, right; // можно обойтись вообще одним итератором (а при известной ловкости - даже только it)
    
    bool const left_ok  = (left=it)==cont.begin()  || cmp()(*(--left),value); // *left < value
    bool const right_ok = ++(right=it)==cont.end() || cmp()(value,*right);    // value < *right
    // для multiset нужно проверять !cmp(value,*left) и !cmp(*right,value),
    // т.е. *left <= value и value <= *right
    
    if(left_ok && right_ok)
        const_cast<Set::key_type&>(*it) = value; // хак
    else // тормоза, зато честно
    {
        cont.erase(it);
        cont.insert(value);
    }
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.