【问题标题】:Extract a c++ variant type from a list of type names从类型名称列表中提取 C++ 变体类型
【发布时间】:2021-09-30 00:12:45
【问题描述】:

我正在设计一个管道类,它需要从过滤器类的不同类型列表中提取std::variant。例如:

template <typename T>
struct Filter {
  using type = T;
  // ...
}

template <typename... Filters>
struct Pipeline {
  
  // how to properly define the variant type?
  // std::variant<Filters::type...> buffer;

};

例如,如果我有三种不同的过滤器类型:

Filter<int>, Filter<double>, Filter<std::string>

那么,变体应该是std::variant&lt;int, double, std::string&gt;。但是,我需要删除变体中的重复类型,例如:

Filter<int>, Filter<double>, Filter<std::string>, Filter<int>

那么,变体不应该是std::variant&lt;int, double, std::string, int&gt;,而是std::variant&lt;int, double, std::string&gt;。此外,我需要将void 替换为std::monostate。例如:

Filter<int>, Filter<double>, Filter<void>, Filter<int>, Filter<void>

那么,变体应该是std::variant&lt;int, double, std::monostate&gt;

如何使用c++17设计这样一个元类,可以根据给定的类型名称template &lt;typename... Filters&gt;正确定义变体类型?

【问题讨论】:

标签: c++ templates c++17 std-variant


【解决方案1】:

基于Piotr's answer

#include <variant>

template <typename T, typename... Ts>
struct unique { using type = T; };

template <typename... Ts, typename U, typename... Us>
struct unique<std::variant<Ts...>, U, Us...>
  : std::conditional_t<(std::is_same_v<U, Ts> || ...), 
                        unique<std::variant<Ts...>, Us...>, 
                        unique<std::variant<Ts..., U>, Us...>> {};

template <typename... Ts>
using variant_t = typename unique<
  std::variant<>, 
  std::conditional_t<std::is_same_v<Ts, void>, std::monostate, Ts>...>::type;

那么您的Pipeline 可以定义为:

template <typename T>
struct Filter {
  using type = T;
};

template <typename... Filters>
struct Pipeline {
  variant_t<typename Filters::type...> buffer;
};

Demo.

【讨论】:

  • 非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多