1

I'm trying to receive values from an unordered map that has std::string as keys, where some of these strings contain only a single character. All my input is coming from a std::stringstream from which I get each value and cast it to a char, and then converting it to a string using
std::string result {1, character};, which seems to be valid according to the documentation and this answer.

However, when I'm doing so the string gets a \x01 prepended (which corresponds to the value 1). This makes the string to not be found in the map. My debugger also confirms that the string is of size 2 with the value "\x01H".

Why is this happening and how can I fix it?

#include <iostream>
#include <sstream>
#include <unordered_map>

int main()
{
    const std::unordered_map<std::string, int> map = { {"H", 1}, {"BX", 2} };

    std::stringstream temp {"Hello world!"};
    char character = static_cast<char>(temp.get());  // character is 'H'
    std::string result {1, character};               // string contains "\x01H"

    std::cout << result << " has length " << result.size() << std::endl; // H has length 2
    std::cout << map.at(result) << std::endl;        // unordered_map::at: key not found
}
Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50

1 Answers1

7

You are using braces {}, not parenthesis (), unlike the question you link to. That makes it an initializer list, not the constructor you were expecting.

kabanus
  • 24,623
  • 6
  • 41
  • 74
  • Aah, such a simple mistake. Thanks for the help! – Ted Klein Bergman Aug 13 '18 at 06:08
  • @melpomene exactly. – kabanus Aug 13 '18 at 06:09
  • 3
    Again another example why one should not use uniform initialisation... Stick with parentheses, that's more explicit; I personally go that far to even use parentheses with initialiser lists: `std::string s({'a', 'b', 'c'})`. (Admitted, there's the problem with trying to explicitly calling the default constructor actually declaring a function instead, but that rule is far less complicated...). – Aconcagua Aug 13 '18 at 06:17