如何从模板参数包中删除类型
How can a type be removed from a template parameter pack?
我正在寻找一种方法从模板参数包中删除(假设现在所有出现的)类型。最终的结果将是如下所示的结构体:
template<typename T, typename...Ts>
struct RemoveT
{
using type = /* a new type out of Ts that does not contain T */
}
假设边际情况RemoveT<int, int>
将通过返回void
来处理(不在后面的代码中处理)。我的初始设计看起来像这样:
// --------------------------------------------------------------
// 1. A "way" of typedefing variadic number of types ------------
template<typename...Ts>
struct pack {
using type = Ts;
};
// --------------------------------------------------------------
// --------------------------------------------------------------
template<typename T, typename...Ts> struct RemoveT;
template<typename T, typename T1, typename...Ts>
struct RemoveT {
using type = typename pack<T1, typename RemoveT<T, Ts...>::type>::type;
};
template<typename T, typename T1>
struct RemoveT<T, T1> {
using type = T1;
};
template<typename T, typename...Ts>
struct RemoveT<T, T, Ts...> {
using type = typename RemoveT<Ts...>::type;
};
// --------------------------------------------------------------
现在我甚至不能开始测试这段代码因为 pack
结构是无效的c++
重复
如果这是一个有帮助的答案,一些关于解决它的其他想法
- 有人可能会说
pack
根本没用。我们可以移动RemoveT
结构体,创建一个只包含所需类型的新RemoveT
。然后问题转变为从结构体 中提取类型。 - 我们可以创建模仿类型列表行为的类型对,并在这方面采用更递归的方法。
对于可变类型Ts
和T
: 我可以在Ts
中创建Us
并提交T
吗?
下面提供了一种非递归的直接方法来从Ts...
中删除T
,并且像Jarod42的解决方案一样,产生std::tuple<Us...>
,但不需要使用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");
}
<<p> 生活例子/strong> 以下内容可能有所帮助:
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, "");
首先,将所有特定的模板名称移到一个列表中。可能有一种方法可以指定模板名称和参数列表,并为该模板提供参数,但我还没能弄清楚:
template <typename...TArgs> struct TypeList
{
typedef std::tuple<TArgs...> tuple_type;
// whatever other types you need
};
接下来,定义加法:
template<typename T, typename TList> struct AddT;
template<typename T, typename ... TArgs>
struct AddT< T, TypeList<TArgs...> >
{
typedef TypeList<T, TArgs... > type;
};
然后定义移除:
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;
};
最后,测试:
int result = 0;
result = std::is_same
< std::tuple<long,double>
, RemoveT<int, int, long, int, double, int>::type::tuple_type
>::value;
assert ( result );
相关文章:
- 从链接列表c++中删除一个项目
- 迭代时从向量和内存中删除对象
- 如何从多映射中删除特定的重复项
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- 如何从给定字符串中删除第二次和第三次出现的$
- 从DLL中删除类的实例
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 你能检查一下为什么在这个代码中从链接列表中删除项目不起作用吗
- 在c++中删除内存失败
- 在虚幻引擎中删除NXOpen对象时崩溃
- 从矢量中删除元素后出现隔离错误
- 从 C 样式字符串中删除子字符串 "in place" 在C++代码中
- 如何从地图中删除矢量对象
- AcquireCredentialsHandleA() 返回 PFX 文件的0x8009030e(安全包中没有可用的凭据
- MSYS2 MinGW程序包中缺少grpc_cpp_plugin协议
- 从矢量或地图中删除共享指针
- 如何在向量中删除 std::function<void()>?
- 从函数参数包中删除最后一项
- 从包中删除某个类型的某些(但不是全部)匹配项
- 如何从模板参数包中删除类型