简体   繁体   English

类特化,没有用作特化模板参数的类的模板参数

[英]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 .并且对latlngpoint都具有direction_trait的特化,而无需为latlngpoint每个可能的模板参数定义特化。

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.我不想在定义latlngpoint的标题中添加与方向相关的信息。

(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.

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