部分C++ STL 容器的模板专用化

Partial C++ Template Specialization with STL containers

本文关键字:专用 C++ STL 部分      更新时间:2023-10-16

所以我的目标是创建一个可以返回不同值的函数或函子。用例是将 Json 对象转换为正确的C++类型。在大多数情况下,我都有这个工作,但我遇到了 std::vectorstd::array 等容器的问题。我知道你不能重载一个函数来只返回不同的值类型,所以我一直在使用具有模板专用化的struct。我想我需要使用部分模板专用化来实现这一点,但我遇到了编译错误。这是我的代码的样子:

template <typename T>
struct from_json
{
    T operator()(const Json::Value &json)
    {
        return T::fromJson(json);
    }
};
template <>
struct from_json<std::string>
{
    std::string operator()(const Json::Value &json)
    {
        return std::string(json.asCString());
    }
};
template <typename T>
struct from_json<std::vector<T> >
{
    std::vector<T> operator()(const Json::Value &json)
    {
        std::vector<T> vector;
        for (auto obj : json)
            vector.push_back(from_json(obj));
        return vector;
    }
};

关于代码片段的一些说明:我有一个抽象类,它要求fromJson由我自己的可序列化类实现,这就是一般情况。std::string概括似乎工作正常。std::vector是事情破裂的地方。编译器认识到这是应该使用的专用化,但在尝试实际使用它时会给出错误。

std::vector<std::string> my_vector = from_json<std::vector<std::string> >(json["my_vector"]);

编译器错误如下:

error: no matching function for call to 'from_json<std::vector<std::__cxx11::basic_string<char> > >::from_json(const Json::Value&)'
std::vector<std::string> my_vector = from_json<std::vector<std::string> >(json["my_vector"]);
note: candidate: constexpr from_json<std::vector<std::__cxx11::basic_string<char> > >::from_json()

还值得注意的是,我使用的是C++ 11。

如果有更好的方法,我绝对愿意接受这方面的建议,可以做得更好。

谢谢!

所以在这一行中:

vector.push_back(from_json(obj));

代码中的from_json是具有已定义operator()的类模板。它不是一个函数或一个函数对象(从这个意义上说,它有点像std::hash)。所以你不能调用它 - 你需要调用它的实例化。

我猜你的意思是这样的:

vector.push_back(from_json<T>{}(obj));

或者,如果你属于范围 v3:

std::vector<T> operator()(const Json::Value &json)
{
    return json | view::transform(from_json<T>{});
}