C++容器类型面临问题,例如从 map<long 无符号 int ..> 转换为非标量类型 map<short unsigned int, ..>


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

相反,你必须做两个选项之一:

  1. 只使用layoutJson中现有的映射类型。这是最好的选择,因为开销更少,像";如果键不适合uint16t,会发生什么&";。您可以使用auto来避免查找和键入长类型名称:

    auto output = layoutJson["MapUInt64String16VectFloat64ReqProvOp"]["value"];
    
  2. 如果不能执行#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开始就不推荐使用,它可能会在以后的标准中被删除。您可能想考虑使用众多库中的一个来进行编码转换,而不是使用标准库(尽管这个建议听起来很奇怪(。

相关内容

最新更新