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

时间:2016-03-20 19:36:37

标签: c++ templates c++11 stl

所以我的目标是创建一个可以返回不同值的函数或函子。用例是将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。

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

谢谢!

1 个答案:

答案 0 :(得分:2)

所以在这一行:

vector.push_back(from_json(obj));
代码中的

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

我猜你的意思是:

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

或者如果你进入range-v3:

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