[英]class specialization, without the template arguments of the class that is used as template argument for specialization
I currently work on a geo library, and I want to have a general-purpose vector class that can be used for lat/lng points, and projected points.我目前在一个地理库上工作,我想要一个通用的向量类,可用于经纬度点和投影点。
The direction for lat/lng points ist described by bearing and a length and the one in the projected space by a 2d vector and a length.纬度/经度点的方向由方位和长度描述,投影空间中的方向由二维向量和长度描述。
So the class should look like:所以这个类应该是这样的:
template <typename T>
struct vector {
direction_t direction;
lenght_t length;
};
The lat/lng point is defined as:纬度/经度点定义为:
template <angle_unit T>
struct latlng {
…
};
And the point is defined as:并且该点被定义为:
template <typename projection_t,typename T = double>
struct point {
…
};
So my initial idea was to define direction_t
as direction_trait<T>::direction_type direction
:所以我最初的想法是将direction_t
定义为direction_trait<T>::direction_type direction
:
template <typename T>
struct vector {
using direction_t = direction_trait<T>::direction_type;
direction_t direction;
lenght_t length;
};
And have a specialization of direction_trait
for both latlng
and point
, without the need to define the specialization for each of the possible template parameters for latlng
and point
.并且对latlng
和point
都具有direction_trait
的特化,而无需为latlng
和point
每个可能的模板参数定义特化。
How can I have something like:我怎么能有这样的东西:
template <typename T>
struct direction_trait;
template <latlng>
struct direction_trait {
using direction_t = double;
};
I don't want to add info that are related to the direction to the header where latlng
or point
is defined.我不想在定义latlng
或point
的标题中添加与方向相关的信息。
(I already figured out a way how to solve it while I was writing the question, but if there is a more elegant way how to solve that problem, without that helper class I would be happy to know it) (我在写问题的时候已经想出了一种解决方法,但是如果有一种更优雅的方法来解决这个问题,如果没有那个帮助类,我会很高兴知道的)
The following works as you wish:以下工作如您所愿:
#include <type_traits> // only for is_same_v in the tests
using angle_unit = int; // just so it compiled
template <angle_unit T>
struct latlng {
};
template <typename projection_t, typename T = double>
struct point {
};
template<typename T>
struct direction_trait;
template<angle_unit T>
struct direction_trait<latlng<T>> {
using direction_type = double;
};
template<typename projection_t, typename T>
struct direction_trait<point<projection_t, T>> {
using direction_type = T; // Or whatever you want
};
template <typename T>
struct vector {
using direction_t = typename direction_trait<T>::direction_type;
direction_t direction;
};
// Usage
static_assert(std::is_same_v<vector<latlng<5>>::direction_t, int>);
static_assert(std::is_same_v<vector<point<long>>::direction_t, double>);
static_assert(std::is_same_v<vector<point<long, float>>::direction_t, float>);
The solution I came up with is the following, to use a declaration of a class that is solely used for the specialization, and a reference to that class to the class body of latlng (point), using using trait = latlng_trait;
我想出的解决方案如下,使用仅用于专业化的类的声明,以及对该类的引用到 latlng(点)的类主体, using trait = latlng_trait;
. . This alias is then used by the vector the get the direction type.然后向量使用这个别名来获取方向类型。
The latlng class: latlng 类:
struct latlng_trait; // a declaration of a class solely used for template specialization
template <angle_unit T>
struct latlng {
using trait = latlng_trait;
…
}
The specialization for latlng: latlng 的专业化:
template <>
struct direction_trait<latlng_trait> {
using direction_t = double;
};
The vector:向量:
template <typename T>
struct vector {
typename direction_trait<typename T::trait>::direction_t direction;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.