给定可变整数列表,生成 class 个模板的元组
Generate tuple of class templates given variadic integer list
我需要生成一个 class 模板的元组,给定一个整数列表作为可变参数。我想要实现的结果显示在下面的示例中,但没有编译:
template <unsigned int First, unsigned int... Is>
using remove_first = std::integer_sequence<unsigned int, Is...>;
template <unsigned int... Is, unsigned int Last> // Invalid
using remove_last = std::integer_sequence<unsigned int, Is...>;
template <unsigned int N_prev, unsigned int N>
class A
{};
template <unsigned int... Is>
class B
{
std::tuple<A<remove_last<Is>, remove_first<Is>>...> object;
};
int main()
{
B<3, 4, 6, 2> b; // <<= b.object is of type: std::tuple<A<3,4>, A<4,6>, A<6,2>>
}
是否可以通过类似的方式实现?
首先 - 可变参数包,一般来说,必须是最后一个 - 所以这不会编译:
template <unsigned int... Is, unsigned int Last> // Invalid
using remove_last = std::integer_sequence<unsigned int, Is...>;
但您不需要 remove_first 或 remove_last。您需要将这些对 A<_, _>
一对一地存储在辅助模板的内部模板中。当我想在这个玩具中实现平面联合时,我发明了(当然,我不知道我是第一个)这种技术 project。
这里是带注释的代码:
#include <tuple>
#include <type_traits>
template <unsigned int N_prev, unsigned int N>
class A
{};
// The helper type
template <unsigned int... Is>
struct DefineAPairs;
template <unsigned int I1, unsigned I2, unsigned int... Is>
struct DefineAPairs<I1, I2, Is...>
{
// in the following line pair A<I1, I2> is added at the proper
// position in nested DefineAPairs
template <typename ...FirstPairs>
using type = typename DefineAPairs<I2, Is...>
::template type<FirstPairs..., A<I1, I2>>;
// here ^^^^^^^^^
};
template <unsigned int I1, unsigned I2>
struct DefineAPairs<I1, I2>
{
// this is sentinel implementation
template <typename ...FirstPairs>
using type = std::tuple<FirstPairs..., A<I1, I2>>;
};
template <unsigned int... Is>
class B
{
public:
using type = typename DefineAPairs<Is...>::template type<>;
type object;
};
int main()
{
B<3, 4, 6, 2> b; // <<= b.object is of type: std::tuple<A<3,4>, A<4,6>, A<6,2>>
// the proof it works
static_assert(std::is_same<std::tuple<A<3,4>, A<4,6>, A<6,2>>,
decltype(b.object)>::value);
}
和demo.
我需要生成一个 class 模板的元组,给定一个整数列表作为可变参数。我想要实现的结果显示在下面的示例中,但没有编译:
template <unsigned int First, unsigned int... Is>
using remove_first = std::integer_sequence<unsigned int, Is...>;
template <unsigned int... Is, unsigned int Last> // Invalid
using remove_last = std::integer_sequence<unsigned int, Is...>;
template <unsigned int N_prev, unsigned int N>
class A
{};
template <unsigned int... Is>
class B
{
std::tuple<A<remove_last<Is>, remove_first<Is>>...> object;
};
int main()
{
B<3, 4, 6, 2> b; // <<= b.object is of type: std::tuple<A<3,4>, A<4,6>, A<6,2>>
}
是否可以通过类似的方式实现?
首先 - 可变参数包,一般来说,必须是最后一个 - 所以这不会编译:
template <unsigned int... Is, unsigned int Last> // Invalid
using remove_last = std::integer_sequence<unsigned int, Is...>;
但您不需要 remove_first 或 remove_last。您需要将这些对 A<_, _>
一对一地存储在辅助模板的内部模板中。当我想在这个玩具中实现平面联合时,我发明了(当然,我不知道我是第一个)这种技术 project。
这里是带注释的代码:
#include <tuple>
#include <type_traits>
template <unsigned int N_prev, unsigned int N>
class A
{};
// The helper type
template <unsigned int... Is>
struct DefineAPairs;
template <unsigned int I1, unsigned I2, unsigned int... Is>
struct DefineAPairs<I1, I2, Is...>
{
// in the following line pair A<I1, I2> is added at the proper
// position in nested DefineAPairs
template <typename ...FirstPairs>
using type = typename DefineAPairs<I2, Is...>
::template type<FirstPairs..., A<I1, I2>>;
// here ^^^^^^^^^
};
template <unsigned int I1, unsigned I2>
struct DefineAPairs<I1, I2>
{
// this is sentinel implementation
template <typename ...FirstPairs>
using type = std::tuple<FirstPairs..., A<I1, I2>>;
};
template <unsigned int... Is>
class B
{
public:
using type = typename DefineAPairs<Is...>::template type<>;
type object;
};
int main()
{
B<3, 4, 6, 2> b; // <<= b.object is of type: std::tuple<A<3,4>, A<4,6>, A<6,2>>
// the proof it works
static_assert(std::is_same<std::tuple<A<3,4>, A<4,6>, A<6,2>>,
decltype(b.object)>::value);
}
和demo.