C++ 如何从模板参数包中删除类型?
我正在寻找一种从模板参数包中删除类型的方法(比如现在所有出现的类型)。最终结果将是一个如下所示的结构:C++ 如何从模板参数包中删除类型?,c++,templates,c++11,variadic-templates,template-meta-programming,C++,Templates,C++11,Variadic Templates,Template Meta Programming,我正在寻找一种从模板参数包中删除类型的方法(比如现在所有出现的类型)。最终结果将是一个如下所示的结构: template<typename T, typename...Ts> struct RemoveT { using type = /* a new type out of Ts that does not contain T */ } 现在我甚至无法开始测试这段代码,因为 重复 如果这对回答是有帮助的,那么请考虑其他一些解决方法 有人可能会说,pack一点用处都没有。
template<typename T, typename...Ts>
struct RemoveT
{
using type = /* a new type out of Ts that does not contain T */
}
现在我甚至无法开始测试这段代码,因为
重复
如果这对回答是有帮助的,那么请考虑其他一些解决方法
- 有人可能会说,
一点用处都没有。相反,我们可以绕过pack
结构,创建一个只包含所需类型的新RemoveT
。然后,将问题转化为从结构中提取类型RemoveT
- 我们可以创建模仿类型列表行为的类型对,并在这方面采取更递归的方法李>
Ts
和类型T
:我可以用Ts
ommitingT
创建Us
吗?以下内容可能会有所帮助:
namespace detail
{
template <typename T, typename Tuple, typename Res = std::tuple<>>
struct removeT_helper;
template<typename T, typename Res>
struct removeT_helper<T, std::tuple<>, Res>
{
using type = Res;
};
template<typename T, typename... Ts, typename... TRes>
struct removeT_helper<T, std::tuple<T, Ts...>, std::tuple<TRes...>> :
removeT_helper<T, std::tuple<Ts...>, std::tuple<TRes...>>
{};
template<typename T, typename T1, typename ...Ts, typename... TRes>
struct removeT_helper<T, std::tuple<T1, Ts...>, std::tuple<TRes...>> :
removeT_helper<T, std::tuple<Ts...>, std::tuple<TRes..., T1>>
{};
}
template <typename T, typename...Ts> struct RemoveT
{
using type = typename detail::removeT_helper<T, std::tuple<Ts...>>::type;
};
static_assert(std::is_same<std::tuple<char, float>,
typename RemoveT<int, int, char, int, float, int>::type>::value, "");
名称空间详细信息
{
模板
struct remove_helper;
模板
结构删除辅助程序
{
使用类型=Res;
};
模板
结构removeT_辅助对象:
移除辅助对象
{};
模板
结构removeT_辅助对象:
移除辅助对象
{};
}
模板结构移除
{
使用type=typename detail::removeT_helper::type;
};
静态断言(std::is_same::value,“”);
以下提供了一种非递归和直接的方法,可以从Ts中删除T
。
并且,与Jarod42的解决方案一样,生成std::tuple
,但不需要使用typename…::type
:
#include <tuple>
#include <type_traits>
template<typename...Ts>
using tuple_cat_t = decltype(std::tuple_cat(std::declval<Ts>()...));
template<typename T, typename...Ts>
using remove_t = tuple_cat_t<
typename std::conditional<
std::is_same<T, Ts>::value,
std::tuple<>,
std::tuple<Ts>
>::type...
>;
int main()
{
static_assert(std::is_same<
remove_t<int, int, char, int, float, int>,
std::tuple<char, float>
>::value, "Oops");
}
#包括
#包括
模板
使用tuple_cat_t=decltype(std::tuple_cat(std::declval()…);
模板
使用remove\u t=tuple\u cat\t<
类型名称std::条件<
std::值是否相同,
std::tuple,
std::tuple
>::键入。。。
>;
int main()
{
静态断言(std::是否相同<
移除,
std::tuple
>::值,“Oops”);
}
首先,将所有特定模板名称移出列表。可能有一种方法可以指定模板名称和参数列表,为该模板提供参数,但我一直无法找到:
template <typename...TArgs> struct TypeList
{
typedef std::tuple<TArgs...> tuple_type;
// whatever other types you need
};
模板结构类型列表
{
typedef std::tuple tuple_type;
//你需要什么样的
};
接下来,定义添加:
template<typename T, typename TList> struct AddT;
template<typename T, typename ... TArgs>
struct AddT< T, TypeList<TArgs...> >
{
typedef TypeList<T, TArgs... > type;
};
模板结构添加;
模板
结构添加
{
typedef类型列表类型;
};
然后,定义删除:
template<typename R, typename ... TArgs> struct RemoveT;
template<typename R>
struct RemoveT<R>
{
typedef TypeList<> type;
};
template<typename R, typename T, typename ...TArgs>
struct RemoveT<R, T, TArgs...>
{
typedef typename std::conditional
< std::is_same<R, T>::value
, typename RemoveT<R, TArgs...>::type
, typename AddT<T, typename RemoveT<R, TArgs...>::type>::type
>::type type;
};
模板结构移除;
模板
结构移除
{
typedef类型列表类型;
};
模板
结构移除
{
typedef typename std::conditional
::类型类型;
};
最后,测试:
int result = 0;
result = std::is_same
< std::tuple<long,double>
, RemoveT<int, int, long, int, double, int>::type::tuple_type
>::value;
assert ( result );
int结果=0;
结果=标准::是否相同
::价值;
断言(结果);
当我在灰质中思考这个问题时,我很好奇我会被用来做什么。例如,什么是示例应用程序?@WhozCraig很好。引用一位伟大的程序员的话:“如果我告诉你,我会杀了你或雇用你”:P。。。当然,好奇的是,你们是对的,你们不能像这里概述的那个样拥有struct-pack
。但是您可以使用std::tuple
例如:typedef std::tuple type代码>这可能是一种快速获取所需内容的方法。这似乎非常广泛。你确定你不是在找留言板或聊天室吗?@DeadMG没有提到你的名字,man(也不是gona)。我没有直接的抱怨,我只是回应了他的轻率。你认为值得投反对票的任何东西都可以投反对票,我不需要知道原因。这是一个很好的答案。不过,作为记录,它没有在VS2013中编译(我承认这并不令人震惊)
int result = 0;
result = std::is_same
< std::tuple<long,double>
, RemoveT<int, int, long, int, double, int>::type::tuple_type
>::value;
assert ( result );