std::map<uint16_t, std::u16string> val = layoutJson["MapUInt64String16VectFloat64ReqProvOp"]["value"];
// string16 to string conversion
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convertor;
std::string actualData = convertor.to_bytes(val.begin()->second);
//ERROR
std::map<uint16_t, std::u16string> receivedData = operationMapUInt64String16VectFloat.GetResult();
CK_EQ(actualData, convertor.to_bytes(receivedData.begin()->second));
我已经尝试了很多方法来解决这个问题,并且我声明的数据类型都是相同的。我仍然得到问题
如果你想直接将一个映射分配给另一个映射,它们不能有不同的键和值类型:
std::map<uint64_t, std::u16string> input;
std::map<uint16_t, std::string> output = input; // error, key and value types are different
相反,你必须做两个选项之一:
只使用
layoutJson
中现有的映射类型。这是最好的选择,因为开销更少,像";如果键不适合uint16t,会发生什么&";。您可以使用auto
来避免查找和键入长类型名称:auto output = layoutJson["MapUInt64String16VectFloat64ReqProvOp"]["value"];
如果不能执行#1,则必须将map元素逐个复制到一个新的map中,将每个元素转换为新的类型。一种惯用的方法是
std::transform
。您将输入容器、输出容器和转换每个元素的函数传递给它:std::map<uint64_t, std::u16string> input = /* ... */; std::map<uint16_t, std::string> output; std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter; std::transform( input.begin(), input.end(), std::inserter(output, output.end()), [&converter](auto& p) { return std::make_pair( static_cast<uint16_t>(p.first), // you probably want to check this converter.to_bytes(p.second)); });
就我个人而言,有时我觉得
<algorithm>
中的内容很难阅读。手动循环也没有错:std::map<uint64_t, std::u16string> input = /* ... */; std::map<uint16_t, std::string> output; std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter; for (auto& p : input) { output.emplace( static_cast<uint16_t>(p.first), // you probably want to check this converter.to_bytes(p.second)); }
FYI,<codecvt>
从C++17开始就不推荐使用,它可能会在以后的标准中被删除。您可能想考虑使用众多库中的一个来进行编码转换,而不是使用标准库(尽管这个建议听起来很奇怪(。