Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何从模板参数包中删除类型?_C++_Templates_C++11_Variadic Templates_Template Meta Programming - Fatal编程技术网

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
ommiting
T
创建
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 );