我想定义一个可变参数元组类型来表示坐标。例如,对于某些魔术类型:
template <unsigned int N>
struct CoordT {
typedef std::tuple<_some_magic_> coord_type;
};
我想将CoordT<3>::coord_type
设为3维坐标类型:
std::tuple<double, double, double>
。
但是我不知道如何使用模板编程来生成N
个重复的double
。
有人可以帮忙解释一下怎么写吗?
答案 0 :(得分:3)
使用std::make_integer_sequence
生成适当长度的包,然后将元素映射为双精度:
template <size_t n>
struct TupleOfDoubles {
template <size_t... i>
static auto foo(std::index_sequence<i...>) {
return std::make_tuple(double(i)...);
}
using type = decltype(foo(std::make_index_sequence<n>{}));
};
答案 1 :(得分:2)
如果您实际上不需要std::tuple
,而只需要类似元组的内容,请使用std::array
:
template <unsigned int N>
struct CoordT {
typedef std::array<double, N> coord_type;
};
std::array
具有std::get<I>
,std::tuple_size
和std::tuple_element
的重载。大多数接受类似元组元素的库和语言设施都将支持std::array
,例如std::apply
和structured bindings。
答案 2 :(得分:0)
玩太晚了吗?
如果可以接受声明(不需要定义),则可变参数模板函数如下所示
template <std::size_t ... Is>
constexpr auto toIndexSeq (std::index_sequence<Is...> a)
-> decltype(a);
并且coord_type
是在CoordT
专业化中定义的,则可以将其编写如下
template <std::size_t N,
typename = decltype(toIndexSeq(std::make_index_sequence<N>{}))>
struct CoordT;
template <std::size_t N, std::size_t ... Is>
struct CoordT<N, std::index_sequence<Is...>>
{ using coord_type = std::tuple<decltype((void)Is, 0.0)...>; };
以下是完整的C ++ 14编译示例
#include <tuple>
#include <type_traits>
template <std::size_t ... Is>
constexpr auto toIndexSeq (std::index_sequence<Is...> a)
-> decltype(a);
template <std::size_t N,
typename = decltype(toIndexSeq(std::make_index_sequence<N>{}))>
struct CoordT;
template <std::size_t N, std::size_t ... Is>
struct CoordT<N, std::index_sequence<Is...>>
{ using coord_type = std::tuple<decltype((void)Is, 0.0)...>; };
int main()
{
using t0 = std::tuple<double, double, double, double>;
using t1 = typename CoordT<4u>::coord_type;
static_assert( std::is_same<t0, t1>::value, "!" );
}
答案 3 :(得分:0)
一种非常简洁的方法是使用std::tuple_cat
和std::array
:
template <unsigned int N>
struct CoordT {
using coord_type = decltype(std::tuple_cat(std::array<double, N>{}));
};
std::tuple_cat
是allowed to support tuple-like types,例如std::array
,但不能保证。但是,我检查了supports this的每个实现。