gpt4 book ai didi

c++ - 具有为实例化固定但随模板参数变化的参数数量的模板方法

转载 作者:可可西里 更新时间:2023-11-01 16:36:49 27 4
gpt4 key购买 nike

我想为带有整数模板参数的模板类定义一个函数,以便函数参数的数量取决于模板参数。这是一个例子:

template< class Coord, int dim >
class Point {
Coord mCoords[ dim ];
public:
void Set( /* I want exactly dim Coord arguments here. */ );
};

我希望编译这段代码:

Point<double,2> pt2d;
pt2d.Set( 25, 32 );
Point<double,3> pt3d;
pt3d.Set( 25, 32, 100 );

此代码失败:

Point<double,2> pt2d;
pt2d.Set( 25, 32, 100 ); // Too many arguments
Point<double,3> pt3d;
pt3d.Set( 25, 32 ); // Too few arguments

现在,我可以手动特化 Point在较小的尺寸中具有不相关的Set功能,但我发现基本上重复相同代码的做法不是 C++ 风格。此外,我不必专门研究 int 模板参数的每个可能值。

是否可以实现 Point<Coord,dim>::Set()恰好需要 dim 的函数Coord 类型的参数无需为 dim 的每个值编写特化代码?

最佳答案

您可以使用 Boost.Hana 用于 getNth 的技巧:

template <typename Coord, int dim, typename = std::make_index_sequence<dim>>
struct Point;

template <typename Coord, int dim, size_t... Ignore>
struct Point<Coord, dim, std::index_sequence<Ignore...>>
{
void Set(decltype(Ignore, Coord{})... args)
{
// ...
}
};

一个更长的版本隐藏了一点Ignore的丑陋(并且适用于非默认构造的Coords ...)将添加一些元编程样板:

template <typename... > struct typelist { };

template <int N, typename T, typename = std::make_index_sequence<N>>
struct repeat;

template <int N, typename T>
using repeat_t = typename repeat<N, T>::type;

template <int N, typename T, size_t... Idx>
struct repeat<N, T, std::index_sequence<Idx...>>
{
template <size_t >
struct makeT { using type = T; };

using type = typelist<typename makeT<Idx>::type...>;
};

然后专注于repeat_t。并将它隐藏在命名空间中,这样用户就不会搞砸了:

namespace details {
template <typename Coord, int dim, typename = repeat_t<dim, Coord>>
struct Point;

template <typename Coord, int dim, typename... dimCoords>
struct Point<Coord, dim, typelist<dimCoords...>>
{
void Set(dimCoords... args)
{

}
};
}

template <typename Coord, int dim>
using Point = details::Point<Coord, dim>;

关于c++ - 具有为实例化固定但随模板参数变化的参数数量的模板方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32913055/

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