Трубопровод от Istringstream к шаблонам

0

У меня есть следующие вопросы: у меня есть карта из string в string которая называется psMap. Т.е. psMap["a"]="20", psMap["b"]="test", psMap["c"]="12.5", psMap["d"]="1" (true) поэтому карта хранит строковые выражения различных типов базовых данных.

Следующая функция foo должна (с учетом ключа) скопировать сопоставленное значение в соответствующую переменную типа, т.е.

int aa;
foo("a", aa); 
=> aa=20.

Явным образом, я хочу иметь одну функцию для всех возможных типов данных (так что вручную не отбрасывать), поэтому я попытался использовать шаблоны, использующие автоматическое преобразование istringsteram, а именно

template<class PARAMTYPE>
void foo(string _name, PARAMTYPE& _dataType) {
    PARAMTYPE buff;
    istringstream(psMap[_name]) >> buff;
    _dataType = buff;
}

Проблема в том, что операция ">>" дает ошибку: Error: no match for "operator>>" in "std::basic_stringstream<char>((*....

Что здесь происходит? stringstream не распознает правильный тип данных и пытается stringstream к абстрактному типу "шаблона"? Как я могу заставить мой код работать?

Танк для ваших усилий :)

  • 0
    Разместите его в >> *buf и *_dataType = *buff; ,
  • 0
    Разве вы не хотите istringstream, а не stringstream?
Показать ещё 2 комментария
Теги:
templates
istringstream

3 ответа

1

Вы создали временный std::istream, что означает, что он не может связываться с неконстантной ссылкой. Некоторые из >> являются функциями-членами, и они будут работать, но другие являются свободными функциями с сигнатурой:

std::istream& operator>>( std::istream&, TargetType& );

и они не будут работать (или даже компилируются).

Чтобы избежать проблемы, просто объявите std::istringstream и используйте его или вызовите функцию-член во временном, который ничего не делает, но возвращает ссылку (не const):

std::istringstream( psMap[name] ).ignore(0) >> buff;

(Лично я считаю, что отдельная переменная более читаема.)

  • 0
    Для обеих версий я получаю ошибку для неоднозначной перегрузки "для оператора >>"
  • 0
    @ Мартин Для какого PARAMTYPE ?
0

Вы используете ссылку в качестве аргумента шаблона, поэтому, если вы вызываете

foo("a", aa);

без ' & it должно быть хорошо (так, как вы пробовали оператор >> для указателя, был нужен). Вам также необходимо изменить последнюю строку шаблона:

_dataType = buff;
  • 0
    не работает с этими изменениями
0

Попробуйте эту реализацию:

template<class R>
R get_value(const std::string& name) {
    R result{};
    std::istringstream buffer{psMap[name]};
    buffer >> result;
    return result;
}

код клиента:

int x  = get_value<int>("a");

Кроме того, не используйте идентификаторы, начинающиеся с символа подчеркивания. Это зарезервировано для разработчиков библиотек.

  • 0
    Re идентификаторы, начинающиеся с подчеркивания: нет. Идентификаторы, начинающиеся со знака подчеркивания и нижнего регистра, зарезервированы только в глобальной области видимости. По крайней мере, не в теории; на практике у меня тоже были проблемы. (Но, конечно, вы никогда не должны начинать или заканчивать переменную подчеркиванием по причинам читабельности.)
  • 0
    Я обычно заканчиваю частные переменные подчеркиванием. Я нахожу их удобочитаемыми, и до сих пор у меня не было проблем ( name_ , value_ , fragments_ и т. Д.).
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню