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

Posted

技术标签:

【中文标题】使用 STL 容器的部分 C++ 模板特化【英文标题】:Partial C++ Template Specialization with STL containers 【发布时间】:2016-03-20 19:36:37 【问题描述】:

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

关于代码 sn-p 的一些说明: 我有一个抽象类,需要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】:

所以在这一行:

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>);

【讨论】:

哇,是的,我完全搞砸了实例。忘记添加 以按照您的建议进行实例化。感谢您指出这一点!

以上是关于使用 STL 容器的部分 C++ 模板特化的主要内容,如果未能解决你的问题,请参考以下文章

STL hash function的模板特化

C++ 函数模板部分特化?

虚拟方法的 C++ 部分模板特化

C++模板—部分特化

[ C++ ] template 模板进阶 (特化,分离编译)

C++模板详解:泛型编程模板原理非类型模板参数模板特化分离编译