模板化类型的模板专业化

时间:2016-01-01 17:51:58

标签: c++ templates

我对c ++模板编程领域很陌生。

我知道我可以专门化功能模板,例如在我的情况下是一个toJson - 函数模板,我想使用ADL。

E.g。

template<typename T>
Json::Value toJson(const T&);

其中Json :: Value由JsonCPP-Library提供。

现在我可以专门针对&#34; normal&#34;像这样的类型:

template<>
Json::Value toJson<MyClass>(const MyClass&)

但是,我有一个类型KalmanFilter<3, 3, 3, double>(很明显,这是完全参数化的),它又有几个Eigen3-Matrices作为类型,其维度是根据KalmanFilter中的整数模板参数确定的。我想像这样专注于Json:

template<>
Json::Value toJson<KalmanFilter<int, int, int, T>>(const KalmanFilter<int, int, int, T> ...)

也许有一种不同的实现方法(例如Eigen重载std :: ostream运算符&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

或者我必须使用不同声明的toJson,例如

template<int A, int B, int C, typename FloatT>
Json::Value toJson(const KalmanFilter<A, B, C, FloatT>&);

2 个答案:

答案 0 :(得分:3)

我会通过使用模板struct并对其进行专门化来解决此问题,而不是专门化功能模板because of potential drawbacks

// Hide implementation details in `impl` namespace.
namespace impl
{
    // Forward-declaration of helper converter struct.
    template<typename>
    struct json_converter;

    // Example specialization: `int`.
    template<>
    struct json_converter<int>
    {
        Json::Value to_json(const int&) 
        { 
            // <Conversion logic here.>
        }
    };

    // Example specialization: `KalmanFilter`.        
    template<int A, int B, int C, typename FloatT>
    struct json_converter<KalmanFilter<A, B, C, FloatT>>
    {
        Json::Value to_json(const KalmanFilter<A, B, C, FloatT>&) 
        { 
            // <Conversion logic here.>
        }
    };
}

// Convenient user-interface function, deduces `T`.
template<typename T>
auto to_json(const T& x)
{
    // Instantiate a temporary `json_converter` and call `to_json`.
    return impl::json_converter<std::decay_t<T>>{}.to_json(x);
}

用法:

KalmanFilter<4, 4, 4, double> kf{/* ... */};
auto result = to_json(kf);

答案 1 :(得分:1)

  

或者我必须使用不同声明的toJson,例如

template<int A, int B, int C, typename FloatT>
Json::Value toJson(const KalmanFilter<A, B, C, FloatT>&);
     

是的,这正是您所需要的。

通过进入功能模板专业化,你会让自己感到困惑。这里绝对没有理由使用函数模板专门化。如果您想要其他类型的转换,只需以相同的方式添加它们:

 template<double A, double B, double C, typename T>
 Json::Value toJson(const OtherFilter<A, B, C, T>&);

如果在不同的命名空间中有不同的类型,则使用具有多个特化的单个函数模板将不与ADL配合。每个toJson函数都需要位于其参数类型的命名空间中。更不用说你可能会惊讶于编译器实际选择使用哪种特化。普通的重载分辨率不那么令人惊讶。

相关问题