C++ Cereal 存档类型专业化不起作用

C++ Cereal Archive Type Specialization not working

我在 VS 2013 中使用 Cereal 1.1.2。

我已经尝试使用此处的类型进行存档专业化示例:http://uscilab.github.io/cereal/archive_specialization.html

但它没有编译错误:

error C2665: 'cereal::make_nvp' : none of the 3 overloads could convert all the argument types ... while trying to match the argument list '(const std::string, const std::string)

我正在尝试使用示例中的片段编译以下代码:

#include "cereal\types\map.hpp"

namespace cereal
{
    //! Saving for std::map<std::string, std::string> for text based archives
    // Note that this shows off some internal cereal traits such as EnableIf,
    // which will only allow this template to be instantiated if its predicates
    // are true
    template <class Archive, class C, class A,
        traits::EnableIf<traits::is_text_archive<Archive>::value> = traits::sfinae> inline
    void save(Archive & ar, std::map<std::string, std::string, C, A> const & map)
    {
        for (const auto & i : map)
            ar(cereal::make_nvp<Archive>(i.first, i.second));
    }

    //! Loading for std::map<std::string, std::string> for text based archives
    template <class Archive, class C, class A,
        traits::EnableIf<traits::is_text_archive<Archive>::value> = traits::sfinae> inline
    void load(Archive & ar, std::map<std::string, std::string, C, A> & map)
    {
        map.clear();

        auto hint = map.begin();
        while (true)
        {
            const auto namePtr = ar.getNodeName();

            if (!namePtr)
                break;

            std::string key = namePtr;
            std::string value; ar(value);
            hint = map.emplace_hint(hint, std::move(key), std::move(value));
        }
    }
} // namespace cereal


#include "cereal\archives\json.hpp"
#include <iostream>
#include <string>
#include <fstream>

int main()
{
    std::stringstream ss;
    {
        cereal::JSONOutputArchive ar(ss);
        std::map<std::string, std::string> filter = { { "type", "sensor" }, { "status", "critical" } };

        ar(CEREAL_NVP(filter));
    }

    std::cout << ss.str() << std::endl;

    {
        cereal::JSONInputArchive ar(ss);
        cereal::JSONOutputArchive ar2(std::cout);

        std::map<std::string, std::string> filter;

        ar(CEREAL_NVP(filter));
        ar2(CEREAL_NVP(filter));
    }

    std::cout << std::endl;
    return 0;
}

请注意,如果我删除 save() 函数重载,它会编译。但是我的目标是能够把map的key当成JSON的key,所以就出来了:

{
    "map": {
        "a": 1,
        "b": 2
    },
    "map_not_string": [
        {
            "key": 1,
            "value": 1
        },
        {
            "key": 2,
            "value": 2
        }
    ]
}

我在 Cereal 的 Github 上提出这个问题并得到了答案: https://github.com/USCiLab/cereal/issues/197

问题是 make_nvp 的模板版本,所以

ar(cereal::make_nvp<Archive>(i.first, i.second));

变成

ar(cereal::make_nvp(i.first, i.second));

文档已更新,因此这应该不再是问题。