簡體   English   中英

C++ 模板元編程中,如何返回模板參數?

[英]In C++ template meta programming, how do you return a template parameter?

template <template <typename...> typename T, template <typename...> typename U>
struct is_same_template : std::false_type {};

template <template <typename...> typename T>
struct is_same_template<T, T> : std::true_type {};

template <template <typename...> typename T, template <typename...> typename U>
constexpr bool is_same_template_v = is_same_template<T, U>::value;

is_same_template的上述實現可以使下面的兩個語句編譯。

static_assert(is_same_template_v<std::map, std::map>);
static_assert(!is_same_template_v<std::map, std::vector>);

是否可以增強is_same_template以便編譯以下語句?

static_assert(is_same_template_v<std::map<int, bool>, std::map>);
static_assert(is_same_template_v<std::map<int, bool>, std::map<int, int>>);
static_assert(!is_same_template_v<std::map<int, bool>, std::vector>);
static_assert(!is_same_template_v<std::map<int, bool>, std::vector<int>>);

由於模板class的模板參數是固定的,所以不能定義一個模板class也叫is_same_template但接受不同的模板參數,而是需要重新定義模板class但復用is_same_template ,即使用模板偏特化得到template 模板參數並將其傳遞給is_same_template

template <typename T, typename U>
struct is_same_template2 : std::false_type {};

template<
  template <typename...> typename T, typename... TArgs,
  template <typename...> typename U, typename... UArgs>
struct is_same_template2<T<TArgs...>, U<UArgs...>> : is_same_template<T, U> {};

template <typename T, template <typename...> typename U>
struct is_same_template3 : std::false_type {};

template <
  template <typename...> typename T, typename... TArgs,
  template <typename...> typename U>
struct is_same_template3<T<TArgs...>, U> : is_same_template<T, U> {};

為了統一接口,可以重載不同的模板函數,使用對應的實現

template <template <typename...> typename T, template <typename...> typename U>
constexpr bool same_template() {
  return is_same_template<T, U>();
}

template <typename T, typename U>
constexpr bool same_template() {
  return is_same_template2<T, U>();
}

template <typename T, template <typename...> typename U>
constexpr bool same_template() {
  return is_same_template3<T, U>();
}

然后你可以這樣調用

static_assert(same_template<std::map, std::map>());
static_assert(!same_template<std::map, std::vector>());
static_assert(same_template<std::map<int, bool>, std::map>());
static_assert(same_template<std::map<int, bool>, std::map<int, int>>());
static_assert(!same_template<std::map<int, bool>, std::vector>());
static_assert(!same_template<std::map<int, bool>, std::vector<int>>());

演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM