gpt4 book ai didi

c++ - 在模板特化中使用非类型模板模板参数

转载 作者:行者123 更新时间:2023-11-30 01:33:31 24 4
gpt4 key购买 nike

我正在学习模板元编程,但在尝试实现某些目标时遇到了障碍我认为这应该是可能的,但我完全不知道该怎么做。

我发现这两个我认为有些相关但没有真正帮助的答案

假设我想表示 1D 和 2D 空间中的点,那么我可以按如下方式定义它们:

template <int X>
struct Point1D {
static constexpr int x = X;
};

template <int X, int Y>
struct Point2D {
static constexpr int x = X;
static constexpr int y = Y;
};

现在我想计算两点之间的距离。一种选择是这样做:

template <typename Point1, typename Point2>
struct Distance {
static constexpr int value = Point2::x - Point1::x;
};

typedef Distance<Point1D<1>, Point1D<5>> dist;
dist::value; //4

然而,这将接受 Point2D 和定义::x 的任何类型

template <int X>
struct RandomType {
static constexpr int x = X;
};

typedef Distance<Point2D<5, 4>, Point1D<2>> dist2; //Should not work
typedef Distance<Point1D<5>, RandomType<6>> dist3; //Should not work either

现在,应该可以为 Point1D 和 Point2D 类型专门化 Distance,但这是我遇到困难的地方。我尝试了以下方法:

template <template <int...> typename Point1, template <int...> typename Point2>
struct Distance {};

template <>
struct Distance<Point1D, Point1D> {
/* Calculate distance between two points */
};

template <>
struct Distance<Point2D, Point2D> {
/* Calculate distance between two points in 2D space */
};

当然,现在我专注于类模板,而不是类型,所以这行不通。我可以将非类型参数传递给特化:

template <template <int...> typename Point1, int N, 
template <int...> typename Point2, int M>
struct Distance {};

template <int N, int M>
struct Distance<Point1D, N, Point1D, M> {
static constexpr int value = Point1D<M>::x - Point1D<N>::x;
};

typedef Distance<Point1D, 2, Point1D, 5> Two;
int x = Two::value; //3

但这违背了目的,因为我只能通过 5 和 2 的距离。我真正需要做的是能够传递任何采用一个 int N 并具有一个成员 X 的类模板,以便我可以使用任何 Point1D<N> 调用 Distance .例如。像这样:

typedef Point1D<4> p1;
typedef Point1D<6> p2;
Distance<p1, p2>::value; //2

typedef Point2D<4, 6> p3;
Distance<p3, p1>::value //Error, can't mix Point1D and Point2D

/* Something of the sort (doesn't compile) */
template<int N, int M>
struct Distance<Point1D<N>, Point1D<M>> {
static constexpr int value = Point1D<N>::x - Point1D<M>::x;
};

从概念上讲,我认为这应该可行,因为在调用 Distance 时,类型包含所有需要的信息。不知何故,通过指定 Distance 采用模板 Point1D<int N>我需要能够调用 Point1D<N>::x 的函数.语法是我无法弄清楚的。

最佳答案

如果我对问题的理解正确,解决方案是声明模板类型 Distance但不定义它,并且只对每对可接受的类型进行部分专门化。例如:

template <typename, typename>
struct Distance;

由于此模板类型没有定义,因此尝试使用任意类型实例化它都会失败,除非类型参数匹配稍后定义的部分特化。

现在部分专注于 Point1D :

template <int ...A, int ...B>
struct Distance<Point1D<A...>, Point1D<B...>> {
static constexpr int value = Point1D<B...>::x - Point1D<A...>::x;
};

您可以将其部分特化为 Point2D通过使用相同的技术并根据需要更改计算:

template <int ...A, int ...B>
struct Distance<Point2D<A...>, Point2D<B...>> {
static constexpr int value = /* ... */;
};

(请注意,int 参数包在技术上是不必要的,因为您知道每种类型使用了多少参数。但是,使用包使部分特化定义彼此保持一致并且使代码更易于维护. 它还强制计算使用值 Point_D<...>::x 而不是仅使用模板参数的值。)

关于c++ - 在模板特化中使用非类型模板模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58397713/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com