繁体   English   中英

可变参数 arguments 都是模板类型的特化

[英]variadic arguments which are all a specialization of a template type

我们可以在编译时验证 function 的输入是模板的特化。 IE 以下代码验证f的输入是 struct Holder 的某种特化。

template<typename T>
struct Holder<T> {...};

template<typename T>
void f(Holder<T> h) {...};

我想验证一组可变参数 arguments 是模板的特化。 更准确地说,我想区分两组连续的可变参数 arguments - 一组是模板的特化,另一组不是。 以下是一个示例,说明如果语法允许它可能会是什么样子 -

template<...Args1, ...Args2>
void f(Holder<Args1>.... args_which_are_specializations_of_Holder, Args2... args_which_are_not) {
  use_holders(args_which_are_specializations_of_Holder...);
  use_rest(args_which_are_not...);
  return;
}

这可能吗?

谢谢,

您可以将args存储在一个tuple中并计算最后一个Holder参数的索引,然后通过索引提取Holder和普通arguments并将它们转发到相应的function。

#include <tuple>

template<class T>
constexpr bool is_holder = false;
template<class T>
constexpr bool is_holder<Holder<T>> = true;

template<class... Args>
void f(Args... args) {
  constexpr auto holder_index = (is_holder<Args> + ... + 0);
  auto args_tuple = std::tuple(args...);

  [&args_tuple]<auto... Is>(std::index_sequence<Is...>) {
    use_holders(std::get<Is>(args_tuple)...);
  }(std::make_index_sequence<holder_index>{});

  [&args_tuple]<auto... Is>(std::index_sequence<Is...>) {
    use_rest(std::get<Is + holder_index>(args_tuple)...);
  }(std::make_index_sequence<sizeof...(Args) - holder_index>{});
}

演示

像这样混合可变参数 arguments 更难。 您可以使用std::tuple

#include <tuple>
#include <cstdio>

template<typename T>
struct Holder {

};

template <class ...T1, class ...T2>
void f(const std::tuple<Holder<T1>...>& holders, const std::tuple<T2...>& non_holders) {
  std::printf("Holder count: %zu\n"
              "Non Holder count: %zu", sizeof...(T1), sizeof...(T1));
}

int main() {
  Holder<int> a;
  Holder<double> b;
  int c;
  double d;  

  f(std::tuple{a, b}, std::tuple{c, d});
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM