I found Some thing on visual studio v143 tools std:c lastest is it bug or something
std::unordered_map<std::string, std::string> map;
std::string test_str = "1234567890123456789012345678901234567890123456789012345";//55 LEN String
map["test_len"] = test_str.length();
std::cout << map["test_len"]; // 7 on 55 len string
CodePudding user response:
In statement
map["test_len"] = test_str.length();
std::unordered_map::operator[]
default-constructs a new std::string
and returns a reference to it which is then assigned to a value of type size_type
. This assignment invokes std::string::operator=(char)
which interprets integer value 55
as ascii character 7
.
This is a long standing usability bug in std::string
interface. Examples of the bug:
std::string s = test_str.length(); // Compiler error.
std::string s2;
s2 = test_str.length(); // Compiles successfully, std::string interface bug.
s2 = true; // Compiles successfully, std::string interface bug.
s2 = std::ios_base::failbit; // Compiles successfully, std::string and std::ios_base interface bugs.
std::string s3{std::ios_base::failbit, 55, true, 'a'}; // Compiles successfully, std::string interface bug.
std::string s3 = {std::ios_base::failbit, 55, true, 'a'}; // Compiles successfully, std::string interface bug.
C 17 type-safe way to insert or assign a value into an associative container is:
map.insert_or_assign("test_len", test_str.length()); // Compiler error.
map.insert_or_assign("test_len", {std::ios_base::failbit, 55, true, 'a'}); // Compiler error.
map.insert_or_assign("test_len", std::to_string(test_str.length())); // Success.
std::unordered_map::insert_or_assign
always uses direct-initialization of mapped value to avoid precisely this kind of silent unanticipated type conversion bugs when value type assignment operator has different semantics from its constructor, which breaks the engineering principle of least surprise.
CodePudding user response:
You try to put length()
to a string
-> string
map. What you need instead is to put to_string()
of it:
#include <unordered_map>
#include <string>
#include <iostream>
int main() {
std::unordered_map<std::string, std::string> map;
std::string test_str = "1234567890123456789012345678901234567890123456789012345";//55 LEN String
map["test_len"] = std::to_string(test_str.length());
std::cout << map["test_len"];
}
Note that std::string
does have a ctor from a char, as in Maxim's answer, hence your code is not an error, just not what you expected it to be.