我对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>&);
答案 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
函数都需要位于其参数类型的命名空间中。更不用说你可能会惊讶于编译器实际选择使用哪种特化。普通的重载分辨率不那么令人惊讶。