使用C ++ 11/14 / 1z,是否有可能使用带有两个参数包的模板化构造,并且在其中,实例化一些其他模板化构造,其中两个包是交错的?即,如果第一个包是T1_1,T1_2,T1_3,第二个包是T2_1,T2_2和T2_3,则交织包将是T1_1,T2_1,T1_2,T2_2,T1_3,T2_3?我的猜测是" no",因为省略号不应该适用于两个参数包元素指示符;但也许某种元组构造或递归实例化技巧可行吗?
编辑:让我明确假设包具有相同的长度(Node *aux,*prev;
prev = *l;
aux = prev->next;
if(aux == NULL)
{
free(prev);
*l = NULL;
return;
}
值)。对于不同长度的包装的解决方案将是不错的,只要它不会让事情变得更加复杂。
答案 0 :(得分:2)
使用功能和decltype
s,您可以轻松地执行此操作
这是一个有效的例子:
#include<tuple>
template<std::size_t... I>
constexpr auto f(std::index_sequence<I...>, auto tup1, auto tup2) {
return std::tuple_cat(std::make_tuple(std::get<I>(tup1), std::get<I>(tup2))...);
}
template<typename... V>
struct S {
template<typename... U, std::enable_if_t<(sizeof...(V) == sizeof...(U))>* = nullptr>
static auto generate() {
return f(std::make_index_sequence<sizeof...(U)>(), std::tuple<V...>{}, std::tuple<U...>{});
}
};
int main() {
static_assert(
std::is_same<
decltype(S<int, double>::template generate<char, void*>()),
std::tuple<int, char, double, void*>
>::value,
"!"
);
}
答案 1 :(得分:2)
使用document.getElementById("myfrndDetails").innerHTML = "lastname - " + frndLst[onefrnd].lastName + " and phoneNumber " + frndLst[onefrnd].phoneNumber ;
是过度的。更不用说不必要的约束了。
琐碎的包类:
tuple_cat
可变的连续,写得相当简单:
template<class...> struct pack {};
然后交错本身同样微不足道 - 扩展为两种类型的包,然后将它们连接起来:
template<class T = pack<>, class...>
struct concat { using type = T; };
template<class... T1, class... T2, class... Ts>
struct concat<pack<T1...>, pack<T2...>, Ts...>
: concat<pack<T1..., T2...>, Ts...> {};
template<class... Ts>
using concat_t = typename concat<Ts...>::type;
答案 2 :(得分:1)
实际上,所有单件都已添加到标准中。我现在无法自己测试,但这个想法应该有用。
template <class Tuple1, class Tuple2, std::size_t ... indices>
auto interleave(Tuple1 t1, Tuple2 t2, std::integer_sequence<std::size_t, indices...>)
{
return std::tuple_cat(std::make_tuple(std::get<indices>(t1),
std::get<indices>(t2))...);
}
template <class Tuple1, class Tuple2>
auto interleave(Tuple1 t1, Tuple2 t2)
{
return interleave(t1, t2, std::make_index_sequence<std::tuple_size<Tuple1>::value>());
}
答案 3 :(得分:0)
当然可以。您可以通过包装器获得两个不同的包:
template < typename L0, typename L1 >
struct interleave;
template < typename ... Pack >
struct pack {};
template < typename ... P0, typename ... P1 >
struct interleave<pack<P0...>, pack<P1...>>
{
using type = ???;
};
答案 4 :(得分:0)
#include <tuple>
#include <iostream>
#include <utility>
#include <typeinfo>
template<class T1, class T2>
struct interleave
{
static constexpr std::size_t size = std::tuple_size<T1>::value;
static_assert(size == std::tuple_size<T2>::value, "");
template<class T> struct impl;
template<std::size_t...Is>
struct impl<std::index_sequence<Is...>>
{
using type = std::tuple
<
std::tuple<std::tuple_element_t<Is, T1>,
std::tuple_element_t<Is, T2>>...
>;
};
template<class T> struct dedup;
template<class...Ts>
struct dedup<std::tuple<Ts...>>
{
using type = decltype(std::tuple_cat(std::declval<Ts>()...));
};
using dups = typename impl<decltype(std::make_index_sequence<size>())>::type;
using type = typename dedup<dups>::type;
};
int main()
{
using t = interleave<std::tuple<int, char, float>, std::tuple<unsigned, double, const char*>>::type;
std::cout << typeid(t).name() << std::endl;
}
答案 5 :(得分:0)
<强>目的:强>
获取类型别名:
Foo<int, double, char, const char*>
使用2个参数包:
using Pack1 = Pack<int, char>;
using Pack2 = Pack<double, const char*>;
然后交错它们:
typename ToFoo<Pack1, Pack2>::type
并执行相同的static_assert
:
using T1 = Foo<int, double, char, const char*>;
using T2 = typename ToFoo<Pack<int, char>, Pack<double, const char*>>::type;
static_assert(std::is_same<T1, T2>::value, "passed");
<强>解决方案:强>
我们可以将2个元组交错为1,如下所示:
template <class Tuple1, class Tuple2, std::size_t ... indices>
auto interleave(Tuple1 t1, Tuple2 t2, std::integer_sequence<std::size_t, indices...>)
{
return std::tuple_cat(std::make_tuple(std::get<indices>(t1),
std::get<indices>(t2))...);
}
template <class Tuple1, class Tuple2>
auto interleave(Tuple1 t1, Tuple2 t2)
{
return interleave(t1, t2, std::make_index_sequence<std::tuple_size<Tuple1>::value>());
}
我们可以得到如下结果的交错元组的类型:
template<typename... Ts>
struct Pack
{
using type = std::tuple<Ts...>;
};
template<typename T0, typename T1>
struct Interleaved;
template<typename... P0, typename... P1>
struct Interleaved<Pack<P0...>, Pack<P1...>>
{
using Pack0 = typename Pack<P0...>::type;
using Pack1 = typename Pack<P1...>::type;
using type = decltype(interleave(std::declval<Pack0>(), std::declval<Pack1>()));
};
然后我们可以使用std::tuple<Ts...>
类型并将其“转换”为Foo<Ts...>
,如下所示:
template<typename T>
struct TupleToFoo;
template<typename... Ts>
struct TupleToFoo<std::tuple<Ts...>>
{
using type = Foo<Ts...>;
};
最后,我们将一个辅助类ToFoo
包装起来,它需要2 Packs
并定义一个类型别名:
template<typename T0, typename T1>
struct ToFoo;
template<typename... P0, typename... P1>
struct ToFoo<Pack<P0...>, Pack<P1...>>
{
using type = typename TupleToFoo<typename Interleaved<Pack<int, char>, Pack<double, const char*>>::type>::type;
};
完整的工作示例:(coliru)
#include <tuple>
template <class Tuple1, class Tuple2, std::size_t ... indices>
auto interleave(Tuple1 t1, Tuple2 t2, std::integer_sequence<std::size_t, indices...>)
{
return std::tuple_cat(std::make_tuple(std::get<indices>(t1),
std::get<indices>(t2))...);
}
template <class Tuple1, class Tuple2>
auto interleave(Tuple1 t1, Tuple2 t2)
{
return interleave(t1, t2, std::make_index_sequence<std::tuple_size<Tuple1>::value>());
}
template<typename... Ts>
struct Pack
{
using type = std::tuple<Ts...>;
};
template<typename T0, typename T1>
struct Interleaved;
template<typename... P0, typename... P1>
struct Interleaved<Pack<P0...>, Pack<P1...>>
{
using Pack0 = typename Pack<P0...>::type;
using Pack1 = typename Pack<P1...>::type;
using type = decltype(interleave(std::declval<Pack0>(), std::declval<Pack1>()));
};
template<typename... Ts>
struct Foo
{};
template<typename T>
struct TupleToFoo;
template<typename... Ts>
struct TupleToFoo<std::tuple<Ts...>>
{
using type = Foo<Ts...>;
};
template<typename T0, typename T1>
struct ToFoo;
template<typename... P0, typename... P1>
struct ToFoo<Pack<P0...>, Pack<P1...>>
{
using type = typename TupleToFoo<typename Interleaved<Pack<int, char>, Pack<double, const char*>>::type>::type;
};
int main()
{
using T1 = Foo<int, double, char, const char*>;
using T2 = typename ToFoo<Pack<int, char>, Pack<double, const char*>>::type;
static_assert(std::is_same<T1, T2>::value, "passed");
return 0;
}