Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> stringstream в map . Как? 
:(
    Опции темы
RinOSpro
Дата 22.11.2011, 15:46 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Всем привет!

Как правильно написать и использовать нечто подобное: 

Код

map<string, auto_ptr<stringstream> > params;

// params["name"] << val;



  Вверх
bsa
Дата 22.11.2011, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



RinOSpro, никак. auto_ptr нельзя использовать внутри контейнеров. И вообще, почитай про него подробней.
PM   Вверх
boostcoder
Дата 22.11.2011, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



RinOSpro, помимо того о чем написал bsa, тебе еще нужно будет самому создавать объекты stringstream`а.
Код

#include <iostream>
#include <sstream>
#include <map>
#include <memory>

int main() {
   std::map<std::string, std::unique_ptr<std::stringstream>> map;
   map["1"].reset(new std::stringstream);
   *map["1"] << "bla bla bla";
   
   std::cout << map["1"]->str() << std::endl;
}


http://liveworkspace.org/code/46dae6131663...28d11c772845fb0
PM WWW   Вверх
RinOSpro
Дата 22.11.2011, 16:03 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата(bsa @  22.11.2011,  15:53 Найти цитируемый пост)
RinOSpro, никак. auto_ptr нельзя использовать внутри контейнеров. И вообще, почитай про него подробней.


Дело не в auto_ptr, а в stringstream... можно ли stringstream каким то другим способом засунуть в контейнер?
  Вверх
bsa
Дата 22.11.2011, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



RinOSpro, конечно. засовывай в контейнер указатель на поток и все. В чем проблема? Вот только делать:
Код
*map["1"] << "bla bla";
Не очень безопасно. Так как нет проверки на существование записи с ключом "1". Поэтому надо делать так:
Код
....::const_iterator it = map.find("1");
if (it == map.end())
   //ошибка
*it->second << "bla bla";


Это сообщение отредактировал(а) bsa - 22.11.2011, 16:08
PM   Вверх
RinOSpro
Дата 22.11.2011, 16:13 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата(boostcoder @  22.11.2011,  16:03 Найти цитируемый пост)
std::map<std::string, std::unique_ptr<std::stringstream>> map;

А счастье было так возможно...)
Цитата

This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. 


Цитата(bsa @  22.11.2011,  16:08 Найти цитируемый пост)
Не очень безопасно. Так как нет проверки на существование записи с ключом "1". Поэтому надо делать так:

Еще и грозит утечками...
  Вверх
boostcoder
Дата 22.11.2011, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(RinOSpro @  22.11.2011,  16:13 Найти цитируемый пост)
А счастье было так возможно...)

в подписи компилятор ;)
PM WWW   Вверх
bsa
Дата 22.11.2011, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(RinOSpro @  22.11.2011,  17:13 Найти цитируемый пост)
А счастье было так возможно...)

попробуй добавить ключ компиляции -std=c++11
Цитата(RinOSpro @  22.11.2011,  17:13 Найти цитируемый пост)
Еще и грозит утечками... 

что и кому? при использовании unique_ptr не грозит.

PM   Вверх
boostcoder
Дата 22.11.2011, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(bsa @  22.11.2011,  16:20 Найти цитируемый пост)
-std=c++11

нее. этот только в 4.7.х появился.

Добавлено через 1 минуту и 24 секунды
RinOSpro, а ключи известны заранее?
PM WWW   Вверх
bsa
Дата 22.11.2011, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



хорошо, в более старых есть -std=c++0x
PM   Вверх
borisbn
Дата 22.11.2011, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(bsa @  22.11.2011,  16:30 Найти цитируемый пост)
хорошо, в более старых есть -std=c++0x

не пойму, почему в современных это не включено по-default'у...


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
bsa
Дата 23.11.2011, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



потому же, почему и C99 не включено в компиляторах С - для совместимости со старым ПО.
PM   Вверх
RinOSpro
Дата 23.11.2011, 11:59 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Компилятор Qt Creator 2.0.1, Основан на Qt 4.7.0 (32-х битной)
Включил (вроде как) поддержку C++0x таким образом:

Цитата

if win32{
    QMAKE_CXXFLAGS += -std=gnu++0x
}
else {
    QMAKE_CXXFLAGS += -std=c++0x
}


Но при компиляции выдает такую ошибку:
Цитата

error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >, _Tp_Deleter = std::default_delete<std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> > >]


Цитата(boostcoder @  22.11.2011,  16:23 Найти цитируемый пост)
RinOSpro, а ключи известны заранее?

Какие ключи?

Это сообщение отредактировал(а) RinOSpro - 23.11.2011, 11:59
  Вверх
bsa
Дата 23.11.2011, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(RinOSpro @  23.11.2011,  12:59 Найти цитируемый пост)
Какие ключи?

ключи map'а - то что в квадратных скобках.
Цитата(RinOSpro @  23.11.2011,  12:59 Найти цитируемый пост)
Но при компиляции выдает такую ошибку:

http://stackoverflow.com/questions/3763621...e-ptr-gcc-4-4-4
PM   Вверх
RinOSpro
Дата 23.11.2011, 13:31 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата(boostcoder @  22.11.2011,  16:23 Найти цитируемый пост)
RinOSpro, а ключи известны заранее?

да.


Цитата(bsa @  23.11.2011,  12:51 Найти цитируемый пост)
http://stackoverflow.com/questions/3763621...e-ptr-gcc-4-4-4

Не понял как это применить к моему случаю, там предлагают использовать std::move. 
Но почему то не получается сделать в связке c map. 

Так работает:
Код

    unique_ptr<stringstream> ss(new stringstream);
    unique_ptr<stringstream> orig(new stringstream);

    *orig << "bla bla bla";
    ss = std::move(orig);


Так не работает:
Код

    map<string, unique_ptr<stringstream> > map;
    unique_ptr<stringstream> orig(new stringstream);

    *orig << "bla bla bla";
    map["1"] = std::move(orig);

error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>




Это сообщение отредактировал(а) RinOSpro - 23.11.2011, 13:52
  Вверх
boostcoder
Дата 23.11.2011, 14:17 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(RinOSpro @  23.11.2011,  13:31 Найти цитируемый пост)
error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>

чтоб много не думать, используй shared_ptr<>.

по поводу ключей: приведи все возможные.
PM WWW   Вверх
bsa
Дата 23.11.2011, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



видимо потому не работает, что контейнеры используют копирование внутри себя.
PM   Вверх
RinOSpro
Дата 23.11.2011, 14:45 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата(boostcoder @  23.11.2011,  14:17 Найти цитируемый пост)
по поводу ключей: приведи все возможные.


написаны латиницей маленькими буквами. щас их не много к примеру:
Цитата

fillclose
memalpha
perimscale
threshold


Код

map<string, stringstream>

эта конструкция мне нужна что бы хранить параметры в виде имя/значение, а stringstream что бы можно было в любой тип легко преобразовывать.

Код

int num;
string str;
param["num"] >> num;
param["str"] >> str;

  Вверх
bsa
Дата 23.11.2011, 15:17 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(RinOSpro @  23.11.2011,  15:45 Найти цитируемый пост)
stringstream что бы можно было в любой тип легко преобразовывать.
ну ты извращенец!!!
Для этих целей существует такой тип Variant. К сожалению, стандартного нет. А тот что в бусте вообще какой-то странный. Но сделать сам ты его можешь.
Я его в свое время делал так:
Код
#ifndef VARIANT_HPP_
# define VARIANT_HPP_

# include <sstream>
# include <memory>
# include <typeinfo>
# include <algorithm>
# include <string>

//-----------------------------------------------------------------------------
template<typename Type>
inline std::string stringFrom(Type value)
{
    std::ostringstream stream;
    stream << value;
    return stream.str();
}
inline const std::string& stringFrom(const std::string &v) { return v; }
//-----------------------------------------------------------------------------
class DLLEXPORT Variant
{
    template<typename ValueType>
    class Holder;
public:
    Variant() : holder_(0) {}
    Variant(const Variant& v) : holder_(v.holder_ ? v.holder_->clone() : 0) {}

    Variant(const char *v) : holder_( new Holder<std::string>(v) ) {}

    template<typename ValueType>
    Variant(const ValueType &v) : holder_( new Holder<ValueType>(v) ) {}

    ~Variant() { delete holder_; }

    inline const std::type_info& type() const;

    inline Variant& operator=(Variant v);

    template<typename DestType>
    inline DestType cast() const;

    void swap(Variant &v) { std::swap(v.holder_, holder_); }
    bool empty() const throw() { return holder_ == 0; }

    inline bool operator==(const Variant &v) const;
private:
    class PlaceHolder {
    public:
        PlaceHolder(){}
        virtual ~PlaceHolder(){}
        virtual const std::type_info& type() const = 0;
        virtual PlaceHolder* clone() const = 0;
        virtual std::ostream& to_stream(std::ostream &stream) const = 0;
        virtual std::istream& from_stream(std::istream &stream) = 0;
        virtual bool compare(const PlaceHolder &ph) const = 0;
    private:
        PlaceHolder(const PlaceHolder &);
        PlaceHolder& operator=(const PlaceHolder &);
    };
    template<typename ValueType>
    class Holder : public PlaceHolder {
    public:
        Holder(const ValueType &val) : data_(val) {}
        virtual const std::type_info& type() const { return typeid(data_); }
        virtual Holder* clone() const { return new Holder(data_); }
        virtual std::ostream& to_stream(std::ostream &stream) const { return stream << data_; }
        virtual std::istream& from_stream(std::istream &stream) { return stream >> data_; }
        virtual inline bool compare(const PlaceHolder &ph) const;
        const ValueType& data() const throw() { return data_; }
    private:
        ValueType data_;
    };

    template<typename DestType>
    inline void lexical_cast(DestType &v) const;

    PlaceHolder *holder_;
};
//-----------------------------------------------------------------------------
const std::type_info& Variant::type() const
{
    return holder_ ? holder_->type() : typeid(void);
}
//-----------------------------------------------------------------------------
Variant& Variant::operator=(Variant v)
{
    swap(v);
    return *this;
}
//-----------------------------------------------------------------------------
template<typename DestType>
DestType Variant::cast() const
{
    DestType result = DestType();
    if (holder_ != 0) {
        if ( typeid(DestType) == holder_->type() ) {
//            typedef boost::remove_reference<DestType>::type nonref;
            return static_cast<const Holder<DestType>*>(holder_)->data();
        }
        lexical_cast(result);
    }
    return result;
}
//-----------------------------------------------------------------------------
template<typename DestType>
void Variant::lexical_cast(DestType &v) const
{
    DestType x = DestType();
    {
        std::stringstream stream;
        holder_->to_stream(stream);
        stream >> x;
    }
    std::auto_ptr<PlaceHolder> ph( holder_->clone() );
    {
        std::stringstream stream;
        stream << x;
        ph->from_stream( stream );
    }
    if ( !holder_->compare(*ph) )
        throw std::bad_cast("Variant: bad cast");
    std::swap(x, v);
}
//-----------------------------------------------------------------------------
template<>
inline void Variant::lexical_cast(std::string &v) const
{
    std::ostringstream stream;
    holder_->to_stream(stream);
    v = stream.str();
}
//-----------------------------------------------------------------------------
template<>
inline void Variant::lexical_cast(bool &v) const
{
    std::ostringstream stream;
    holder_->to_stream(stream);
    v = boolFromString(stream.str());
}
//-----------------------------------------------------------------------------
bool Variant::operator==(const Variant &v) const
{
    bool e1 = empty();
    bool e2 = v.empty();
    if (e1 || e2)
        return e1 && e2;    //true if both empty
    return holder_->compare(*v.holder_);
}
//-----------------------------------------------------------------------------
template<typename ValueType>
bool Variant::Holder<ValueType>::compare(const PlaceHolder &ph) const
{
    if ( Holder::type() == ph.type() )
        return (static_cast<const Holder&>(ph).data_ == data_);
    std::ostringstream stream1, stream2;
    ph.to_stream(stream1);
    to_stream(stream2);
    return stream1.str() == stream2.str();
}
//-----------------------------------------------------------------------------
template<typename DestType>
inline DestType variant_cast(const Variant& v)
{
    return v.cast<DestType>();
}
//-----------------------------------------------------------------------------
namespace std {
inline void swap(Core::Variant &v1, Core::Variant &v2)
{
    v1.swap(v2);
}
}    //namespace std
//-----------------------------------------------------------------------------
#endif /* VARIANT_HPP_ */


Если добавить операторы << и >>, которые будут вызывать метод cast, то получишь именно необходимую тебе функциональность.

Это сообщение отредактировал(а) bsa - 23.11.2011, 15:20
PM   Вверх
boostcoder
Дата 23.11.2011, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(bsa @  23.11.2011,  15:17 Найти цитируемый пост)
ну ты извращенец!!!
Для этих целей существует такой тип Variant.

с++ славится статической типизацией. по этому, Variant, в любом случае костыль.

RinOSpro, объясни задачу более полно. чего мы тут гадаем...
PM WWW   Вверх
RinOSpro
Дата 23.11.2011, 15:53 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата(boostcoder @  23.11.2011,  15:33 Найти цитируемый пост)
RinOSpro, объясни задачу более полно. чего мы тут гадаем...

В DLL поступают параметры в виде (сhar* name, char* value) (GUI написан на другом языке)
И мне нужно составить пары name -> value.
Что бы потом можно было легко и просто получить параметры примерно так, вне зависимотри от типа:
Код

bool fillclose << param["fillclose"];
float memalpha << param["memalpha"];
int perimscale << param["perimscale"];
int threshold << param["threshold"];


boostcoder блин... и я только щас после того как написал класс обертку (см ниже). понял что туплю... stringstream после <<  будет очищаться....((

Цитата(bsa @  23.11.2011,  15:17 Найти цитируемый пост)
ну ты извращенец!!!

Ты еще не видел что какое чудовище у меня получилось))

Код

class sswraper
{
public:
    auto_ptr<stringstream> s;

    sswraper(const sswraper& ssw)
    {
        stringstream *sn = new stringstream();
        (*sn) << ssw.s.get()->rdbuf();
        s.reset( sn );
    }

    sswraper()
    {
        s.reset(new stringstream);
    }
};

map<string, sswraper> params;

// используем так
    sswraper ssw;
    *ssw.s << avalue;
    params[name] = ssw;

    *(params[name].s) >> sss;



  Вверх
mes
Дата 23.11.2011, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



основных варианта два : обертка над картой или оберка над элементом карты (см вариант)..
но также есть и другие.. если одно имя ключа всегда ассоциируется с одним типом, то можно немножко постараться и сделать приведение в рантайм согласованным..

Добавлено через 3 минуты и 6 секунд
Цитата(boostcoder @  23.11.2011,  14:33 Найти цитируемый пост)
с++ славится статической типизацией. по этому, Variant, в любом случае костыль.

как категорично.. и дисколи прям так и была нацелена на статическую типизацию.. 
однако не статической типизацией единной сыт программист smile





--------------------
PM MAIL WWW   Вверх
Lols
Дата 24.11.2011, 03:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 144
Регистрация: 21.10.2011

Репутация: нет
Всего: нет



Не понял как это применить к моему случаю, там предлагают использовать std::move. 

Я вот тоже. У кого какие мысли по этому поводу?
PM MAIL   Вверх
RinOSpro
Дата 24.11.2011, 09:22 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата(mes @  23.11.2011,  23:28 Найти цитируемый пост)
основных варианта два : обертка над картой или оберка над элементом карты 

Угу так собственно и сделал...

Код

#ifndef PARAMS_H
#define PARAMS_H

#include <map>
#include <string>

using namespace std;

class Params
{
private:
    map<string, string> params;
public:
    string& operator[](string n);

    int Int(string n);
    bool Bool(string n);
    string Str(string n);
    float Float(string n);
    double Double(string n);
};

#endif // PARAMS_H


Код

#include "params.h"
#include <sstream>

string& Params::operator[](string n)
{
    return params[n];
}

int Params::Int(string n)
{
    int result;

    stringstream s;
    s << params[n];
    s >> result;

    return result;
}

float Params::Float(string n)
{
    float result;

    stringstream s;
    s << params[n];
    s >> result;

    return result;
}

double Params::Double(string n)
{
    double result;

    stringstream s;
    s << params[n];
    s >> result;

    return result;
}

bool Params::Bool(string n)
{
    bool result;

    stringstream s;
    s << params[n];
    s >> result;

    return result;
}

string Params::Str(string n)
{
    string result;

    stringstream s;
    s << params[n];
    s >> result;

    return result;
}


Использую так:
Для установки значений 
Код

    params[name] = value;


Для получения значений:
Код

    int threshold = params.Int("threshold");
    int minrect = params.Int("minrect");
    double memalpha = params.Double("memalpha");
    int perimscale = params.Int("perimscale");
    bool fillclose = params.Bool("fillclose");


Если кто поможет написать перегрузку >> что бы работало как в stringstream буду очень благодарен.


Это сообщение отредактировал(а) RinOSpro - 24.11.2011, 09:24
  Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1415 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.