我目前在地理图书馆工作,我想有一个通用的矢量类,可用于经纬度点和投影点。
经度和纬度点的方向由方位角和长度来描述,而投影空间中的经度方向由2d向量和长度来描述。
所以类应该看起来像:
template <typename T>
struct vector {
direction_t direction;
lenght_t length;
};
纬度/经度点定义为:
template <angle_unit T>
struct latlng {
…
};
该点定义为:
template <typename projection_t,typename T = double>
struct point {
…
};
所以我最初的想法是将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;
};
并且对direction_trait
和latlng
都具有point
的特殊化,而无需为latlng
和{{ 1}}。
我怎么有类似的东西:
point
我不想将与方向相关的信息添加到定义了template <typename T>
struct direction_trait;
template <latlng>
struct direction_trait {
using direction_t = double;
};
或latlng
的标题中。
(我在编写问题时已经想出了一种解决方法,但是,如果有一种更优雅的方法来解决该问题,没有该助手类,我将很高兴知道它)
答案 0 :(得分:1)
以下内容可按您的意愿进行:
#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>);
答案 1 :(得分:0)
我想出的解决方案如下:使用仅用于专业化的类的声明,并使用point
使用latlng(点)的类体对该类的引用。然后,矢量将使用此别名获取方向类型。
latlng类:
using trait = latlng_trait;
latlng的专业化
struct latlng_trait; // a declaration of a class solely used for template specialization
template <angle_unit T>
struct latlng {
using trait = latlng_trait;
…
}
向量:
template <>
struct direction_trait<latlng_trait> {
using direction_t = double;
};