0

I have the following questions: I have a map from string to string which is called psMap. I.e. psMap["a"]="20", psMap["b"]="test", psMap["c"]="12.5", psMap["d"]="1" (true) so the map stores string-expressions of various basic-data types.

The following function foo should (given a key), copy the mapped value to a corresponding type variable, i.e;

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

Explicitly, I want to have one function for all possible data-types (so no manually cast), so I tried with templates exploiting the automatic conversion of istringsteram, namely

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

The problem is, that the ">>" operation gives an error: Error: no match for »operator>>« in »std::basic_stringstream<char>((* ....

What is going wrong here? Does the stringstream not recognize the correct data type and tries to pipe into an abstract type of "template"? How could I make my code work?

Tank you for your effort :)

Martin
  • 328
  • 1
  • 6

3 Answers3

1

You've created a temporary std::istream, which means that it cannot bind to a non-const reference. Some of the >> are member functions, and they will work, but others are free functions with the signature:

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

and these will not work (or even compile).

To avoid the problem either Just declare an std::istringstream and use it, or call a member function on the temporary which does nothing, but returns a (non-const) reference:

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

(Personally, I find the separate variable more readable.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
0

You use reference as the template argument, so if you call

foo("a", aa);

without '& it should be fine (the way you tried the operator>> for pointer was needed). You also need to modify the last template line:

_dataType = buff;
Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
0

Try this implementation:

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

client code:

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

Also, do not use identifiers starting with an underscore. That is reserved for library implementers.

utnapistim
  • 26,809
  • 3
  • 46
  • 82
  • Re identifiers starting with an underscore: no. Identifiers starting with an underscore followed by a lower case are only reserved at global scope. At least not in theory; in practice, I've had problems too. (But of course, you should never start _or_ end a variable with an underscore, for reasons of readability.) – James Kanze Jan 31 '14 at 13:58
  • I usually end private variables with an underscore. I find them readable and I've had no problems up to now (`name_`, `value_`, `fragments_`, etc.). – utnapistim Jan 31 '14 at 14:06
  • It depends on the font, but with a lot of fonts, the underscore disappears. As a general rule, using a leading or trailing underscore is very unfriendly to your readers. – James Kanze Jan 31 '14 at 14:10
  • I hadn't even considered the problem of the dissapearing underscore. I will think of an alternative for my personal coding convention :( ... Thanks. – utnapistim Jan 31 '14 at 14:12
  • I get an error for the initializing of the "R result{};" line: result has to be initialized by constructor and not with "{...}" – Martin Jan 31 '14 at 14:32
  • If you are using C++11, it should work (as long as you have a default constructor or R is a POD type). If you are not using a C++11 ompiler, replace the line with `R result = R();` (which still requires a default constructor or a POD type). – utnapistim Jan 31 '14 at 14:37
  • added -std=c++0x and this line goes through. However, I get the same error as above below: ambiguous overload of operator >> – Martin Jan 31 '14 at 14:50
  • Can you write just the `std::istringstream buffer{psMap[name]}; buffer >> result;` code without a function? If you cannot, then it's possible that you're trying to read a value that has no `>>` defined for it. – utnapistim Jan 31 '14 at 14:54