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++;可变模板型滤波变换_C++_Templates_Metaprogramming - Fatal编程技术网

C++ C++;可变模板型滤波变换

C++ C++;可变模板型滤波变换,c++,templates,metaprogramming,C++,Templates,Metaprogramming,问题。 我是模板元编程新手,不确定如何实现 元组上的一种类型过滤转换,当提供该转换时会生成一个类型 具有过滤描述。我相信下面的代码片段演示了 我想要的行为 enum : int { INCLUDE, EXCLUDE }; template <int filter_val, class T> struct filter { }; int main() { struct A {}; struct B {}; struct C {}; typedef std

问题。

我是模板元编程新手,不确定如何实现 元组上的一种类型过滤转换,当提供该转换时会生成一个类型 具有过滤描述。我相信下面的代码片段演示了 我想要的行为

enum : int {
  INCLUDE,
  EXCLUDE
};

template <int filter_val, class T>
struct filter {
};

int
main() {

  struct A {};
  struct B {};
  struct C {};

  typedef std::tuple<filter<INCLUDE, A>,
                     filter<EXCLUDE, B>,
                     filter<INCLUDE, C>> filters;

  typedef filter_all<filters>::type filtered;

  static_assert(std::is_same<filtered,
                             std::tuple<A, C>
                            >::value,
                ":(");

  return 0;
}
enum:int{
包括,,
排除
};
模板
结构过滤器{
};
int
main(){
结构A{};
结构B{};
结构C{};
typedef std::元组过滤器;
typedef filter_all::type filtered;
静态断言(std::is_same::value,
":(");
返回0;
}
我尝试过的

据我所知,你不能解包超过1个独立的变量模板,所以我想解决这个问题的方法是在递归模板专门化过程中维护两个元组,其中一个表示我们在递归中的位置,而另一个表示目前包含的T

template <template <class ...> class, class ...Unfiltered_Ts>
struct filter_all {
private: 
  template <class Unfiltered_Ts_Tuple, class Included_Ts_Tuple>
  struct filter_all_impl;

  // CASE 1: Include T in the result
  template <
    template <int, class> class, int filter_val, class T, class ...Unfiltered_Ts_impl, // Unfiltered input
    template <class ...> class, class ...Included_Ts                                   // Result so far
  >
  struct filter_all_impl<std::tuple<filter<INCLUDE, T>,
                                    Unfiltered_Ts_impl...>,
                         std::tuple<Included_Ts...>> {
    typedef typename
      filter_all_impl<std::tuple<Unfiltered_Ts_impl...>,
                      std::tuple<Included_Ts..., T> // Append T to result
                     >::type type;
  };

  // CASE 2: Don't include T in the result
  template <
    template <int, class> class, int filter_val, class T, class ...Unfiltered_Ts_impl, // Unfiltered input
    template <class ...> class, class ...Included_Ts                                   // Result so far
  >
  struct filter_all_impl<std::tuple<filter<EXCLUDE, T>,
                                    Unfiltered_Ts_impl...>,
                         std::tuple<Included_Ts...>
                        > {
    typedef typename
      filter_all_impl<std::tuple<Unfiltered_Ts_impl...>,
                      std::tuple<Included_Ts...> // Don't append T to result
                     >::type type;
  };

  // CASE 3: Filtering finished - set the final type as the included T's
  template <
    template <int, class> class, int filter_val, class T, class ...Unfiltered_Ts_impl, 
    template <class ...> class, class ...Included_Ts
  >
  struct filter_all_impl<<>, // empty
                         std::tuple<Included_Ts...>
                        > {
    // Final step, set type as a tuple of all included Ts
    typedef std::tuple<Included_Ts...> type;
  };
public:
  typedef typename filter_all_impl<
    std::tuple<Unfiltered_Ts...>, // Initially contains all unfiltered Ts
    std::tuple<>                  // Initially empty filtered Ts which eventually becomes the return type
  >::type type;
};
模板
结构过滤器{
私人:
模板
结构过滤器\u all\u impl;
//案例1:结果中包含T
模板<
模板类,int filter\u val,类T,类…未筛选的\u Ts\u impl,//未筛选的输入
模板类,类…包含\u Ts//到目前为止的结果
>
结构过滤器\u全部\u执行{
typedef typename
过滤器\u所有\u impl::类型;
};
//案例2:结果中不包含t
模板<
模板类,int filter\u val,类T,类…未筛选的\u Ts\u impl,//未筛选的输入
模板类,类…包含\u Ts//到目前为止的结果
>
结构过滤器\u全部\u执行{
typedef typename
过滤所有内容
结构过滤器\u全部\u执行{
//最后一步,将type设置为包含的所有Ts的元组
typedef std::元组类型;
};
公众:
typedef typename过滤器\u all\u impl<
std::tuple,//最初包含所有未筛选的T
std::tuple//最初为空,最终成为返回类型
>::类型类型;
};

我希望有一种更简单的方法来进行此转换,但这是我到目前为止得出的结论,但它远未编译,并且抱怨模板专门化无效。欢迎提供任何指导。

首先,定义一个
pick
帮助器,该帮助器返回排除项的空元组,以及一个包含除此之外:

template <typename>
struct pick;

template <typename T>
struct pick<filter<INCLUDE, T>> { using type = std::tuple<T>; };

template <typename T>
struct pick<filter<EXCLUDE, T>> { using type = std::tuple<>; };
完成了


如果您可以修改
过滤器
的实现以公开
constepr bool
,则它可以更简单:

template <int filter_val, class T>
struct filter 
{
    static constexpr bool pick = filter_val == INCLUDE;
    using type = T;
};

template <typename T>
struct filter_all;

template <typename... Ts>
struct filter_all<std::tuple<Ts...>>
{   
    using type = decltype(std::tuple_cat(
        std::conditional_t<Ts::pick, 
            std::tuple<typename Ts::type>, std::tuple<>>{}...
    ));
};
模板
结构过滤器
{
静态constexpr bool pick=filter_val==INCLUDE;
使用类型=T;
};
模板
结构过滤器;
模板
结构过滤器
{   
使用type=decltype(std::tuple\u cat(
std::条件{}。。。
));
};

希望我能对这个问题投两次赞成票。感谢您的清晰解释、测试驱动程序和展示您的尝试。非常感谢!我很高兴我的混乱没有编译,因为这将更容易管理。尽管我不知道我是否在正确的道路上让它做正确的事情,尽管它很丑陋…
t
might不是默认可构造的(因此
tuple
),因此您应该将
pick::type{}
替换为
std::declval
template <int filter_val, class T>
struct filter 
{
    static constexpr bool pick = filter_val == INCLUDE;
    using type = T;
};

template <typename T>
struct filter_all;

template <typename... Ts>
struct filter_all<std::tuple<Ts...>>
{   
    using type = decltype(std::tuple_cat(
        std::conditional_t<Ts::pick, 
            std::tuple<typename Ts::type>, std::tuple<>>{}...
    ));
};