这个问题分几个部分解决。
在第一部分,让我们创建一个template<typename type_2_search, typename ...all_types> class type_search; 来确定@987654323@ 是否是...all_types 中的任何类型
#include <type_traits>
#include <iostream>
#include <tuple>
template<typename type_2_search, typename ...all_types> class type_search;
template<typename type_2_search,
typename type_2_compare,
typename ...all_types> class type_compare
: public type_search<type_2_search, all_types...>
{
};
template<typename type_2_search,
typename ...all_types>
class type_compare<type_2_search, type_2_search, all_types...>
: public std::true_type {};
template<typename type_2_search>
class type_search<type_2_search> : public std::false_type {};
template<typename type_2_search, typename first_type, typename ...all_types>
class type_search<type_2_search, first_type, all_types...> :
public type_compare<type_2_search, first_type, all_types...>
{
};
int main()
{
std::cout << type_search<int, char, double, int *>::value << std::endl;
std::cout << type_search<int, int, char, double, int *>::value << std::endl;
std::cout << type_search<int, char, double, int *, int>::value << std::endl;
std::cout << type_search<int, char, int, double, int *>::value << std::endl;
}
结果输出是:
0
1
1
1
下一部分是template<typename type, bool value, typename tuple_bag> class add_2_bag_if_type_in_tuple;。第一个参数是类型。第三个参数是std::tuple<types...>。如果第二个bool 是true,模板会返回一个std::tuple<type, types...>,它会添加元组的类型。否则,它会返回相同的元组。相当简单:
template<typename type, bool value, typename tuple_bag>
class add_2_bag_if_type_in_tuple;
template<typename type, typename tuple_bag>
class add_2_bag_if_type_in_tuple<type, false, tuple_bag> {
public:
typedef tuple_bag type_t;
};
template<typename type, typename ...types>
class add_2_bag_if_type_in_tuple<type, true, std::tuple<types...>> {
public:
typedef std::tuple<type, types...> type_t;
};
我们现在有所有缺失的部分来创建tuple_intersection 模板,在最后一部分。我们遍历第一个元组的类型,使用第一个模板检查每个类型与第二个元组中的类型,然后将结果传递给第二个模板。
首先,特化,当我们到达第一个元组类型的末尾时:
template<typename tuple1_types,
typename tuple2_types> class compute_intersection;
template<typename ...tuple2_types>
class compute_intersection<std::tuple<>,
std::tuple<tuple2_types...>> {
public:
typedef std::tuple<> type_t;
};
对于拼图的最后一块:从第一个元组中取出第一个类型,递归使用 compute_intersection 计算第一个元组的其余部分与第二个元组的交集,然后 type_search 被拔出的-off 类型,然后 `add_2_bag_if_type_in_tuple:
template<typename tuple1_type,
typename ...tuple1_types, typename ...tuple2_types>
class compute_intersection<std::tuple<tuple1_type, tuple1_types...>,
std::tuple<tuple2_types...>> {
public:
typedef typename compute_intersection<std::tuple<tuple1_types...>,
std::tuple<tuple2_types...>>
::type_t previous_bag_t;
typedef typename add_2_bag_if_type_in_tuple<
tuple1_type,
type_search<tuple1_type, tuple2_types...>::value,
previous_bag_t>::type_t type_t;
};
完整的测试程序:
#include <type_traits>
#include <iostream>
#include <tuple>
template<typename type_2_search, typename ...all_types> class type_search;
template<typename type_2_search,
typename type_2_compare,
typename ...all_types> class type_compare
: public type_search<type_2_search, all_types...>
{
};
template<typename type_2_search,
typename ...all_types>
class type_compare<type_2_search, type_2_search, all_types...>
: public std::true_type {};
template<typename type_2_search>
class type_search<type_2_search> : public std::false_type {};
template<typename type_2_search, typename first_type, typename ...all_types>
class type_search<type_2_search, first_type, all_types...> :
public type_compare<type_2_search, first_type, all_types...>
{
};
// add_2_bag_if_type_in_tuple adds the type to tuple_bag
//
// The third template parameter is a tuple_bag
//
// If the 2nd template parameter is true, add the first parameter to the
// bag of types, otherwise the bag of types is unchanged.
template<typename type, bool value, typename tuple_bag>
class add_2_bag_if_type_in_tuple;
template<typename type, typename tuple_bag>
class add_2_bag_if_type_in_tuple<type, false, tuple_bag> {
public:
typedef tuple_bag type_t;
};
template<typename type, typename ...types>
class add_2_bag_if_type_in_tuple<type, true, std::tuple<types...>> {
public:
typedef std::tuple<type, types...> type_t;
};
/////////
template<typename tuple1_types,
typename tuple2_types> class compute_intersection;
template<typename ...tuple2_types>
class compute_intersection<std::tuple<>,
std::tuple<tuple2_types...>> {
public:
typedef std::tuple<> type_t;
};
template<typename tuple1_type,
typename ...tuple1_types, typename ...tuple2_types>
class compute_intersection<std::tuple<tuple1_type, tuple1_types...>,
std::tuple<tuple2_types...>> {
public:
typedef typename compute_intersection<std::tuple<tuple1_types...>,
std::tuple<tuple2_types...>>
::type_t previous_bag_t;
typedef typename add_2_bag_if_type_in_tuple<
tuple1_type,
type_search<tuple1_type, tuple2_types...>::value,
previous_bag_t>::type_t type_t;
};
int main()
{
// Test case: no intersection
typedef compute_intersection<std::tuple<int>, std::tuple<char>>::type_t
one_type;
std::tuple<> one=one_type();
// Test case: one of the types intersect
typedef compute_intersection<std::tuple<int, char>,
std::tuple<char, double>>::type_t
two_type;
std::tuple<char> two = two_type();
// Test case, two types intersect, but in different order:
typedef compute_intersection<std::tuple<int, char, int *>,
std::tuple<int *, char, double>>::type_t
three_type;
std::tuple<char, int *> three = three_type();
}