简体   繁体   English

模板化类型的模板化专业化

[英]Template specialization for templatized types

I'm quite new to the realm of c++ template programming. 我是C ++模板编程领域的新手。

I understand that I can specialise function templates, eg in my case a toJson -function template that I want to use using ADL. 我了解我可以专门研究功能模板,例如,在我的情况下,我想使用ADL使用toJson功能模板。

Eg 例如

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

where Json::Value is provided by the JsonCPP-Library. 其中Json :: Value由JsonCPP-Library提供。

Now I can specialise this for "normal" types like this: 现在,我可以将其专门用于“正常”类型,如下所示:

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

Great. 大。

However, I have a type, KalmanFilter<3, 3, 3, double> (obviously, this is fully parametrised) which in turn has several Eigen3-Matrices as type, who's dimension is determined based on the integral template arguments in KalmanFilter. 但是,我有一个类型, KalmanFilter<3, 3, 3, double> 3,3,3 KalmanFilter<3, 3, 3, double> (显然,这是完全参数化的),该类型又有几个Eigen3-Matrices作为类型,其维数是根据KalmanFilter中的积分模板参数确定的。 I would like to specialise toJson like this: 我想像这样专门研究杰森:

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

Maybe there is a different way of achieving this (eg Eigen overloads the std::ostream operator<< generically for all its types). 也许有另一种方法可以实现此目的(例如,Eigen对所有类型的std :: ostream运算符<<通常都进行重载)。

Or do I have to use a differently declared toJson, like 还是我必须使用其他声明的toJson,例如

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

?

I would solve this problem by using a template struct and specializing it, instead of specializing a function template, because of potential drawbacks . 由于存在潜在的缺陷 ,我将通过使用模板struct并对其进行专门化来解决此问题,而不是对功能模板进行专门化。

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

Usage: 用法:

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

Or do I have to use a differently declared toJson, like 还是我必须使用其他声明的toJson,例如

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

?

Yes, that's exactly what you need. 是的,这正是您所需要的。

You're confusing yourself by getting into function template specialization. 您会因进入功能模板专业化而感到困惑。 There's absolutely no reason to use function template specialization here. 这里绝对没有理由使用功能模板专门化。 If you want conversions for other types, just add them in the same way: 如果要转换其他类型,只需以相同的方式添加它们:

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

If you have different types in different namespaces, then using a single function template with multiple specializations will not cooperate with ADL. 如果在不同的名称空间中具有不同的类型,则使用具有多个专业化功能的单个功能模板将无法与ADL配合使用。 Each toJson function needs to be in the namespace of its parameter type. 每个toJson函数都必须位于其参数类型的名称空间中。 Not to mention that you could potentially be surprised by which specialization the compiler actually chooses to use. 更不用说您可能会对编译器实际选择使用哪种专业化感到惊讶。 Ordinary overload resolution is less surprising. 普通的过载解决方案不足为奇。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM