7

のいずれかを取る最近私は、メタ型とコンパイル時の型の連結を可能に可能な操作を設計したテンプレートクラス:Q:ノーマルタイプまたはテンプレートのテンプレート引数

#include <tuple> 

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

/*variable template helper*/ 
template<template<typename...> typename T> 
constexpr MetaTypeTag<T> meta_type_tag = {}; 

template<typename T> 
struct TypeTag 
{}; 

/*comparison*/ 
template<typename T> 
constexpr bool operator==(TypeTag<T>, TypeTag<T>) { return true; } 
template<typename T, typename U> 
constexpr bool operator==(TypeTag<T>, TypeTag<U>) { return false; } 

/*variable template helper*/ 
template<typename T> 
constexpr TypeTag<T> type_tag = {}; 

template<template<typename...> typename T, typename... Ts> 
constexpr TypeTag<T<Ts...>> combine(MetaTypeTag<T>, TypeTag<Ts>...) 
{ 
    return {}; 
} 

int main() 
{ 
    constexpr auto combined_tag = combine(meta_type_tag<std::tuple>, type_tag<int>, type_tag<float>); 
    static_assert(combined_tag == type_tag<std::tuple<int, float>>, ""); 
} 

std::tupleテンプレート引数なしではできませんタイプとして使用することはできますが、テンプレートテンプレートパラメータには引き続き表示されることがあります。

struct MetaTypeTagstruct TypeTagを統合する方法があるかどうかは、1つのテンプレートパラメータを持つ空のクラスであるか、少なくとも同じものを使用できる可能性があるかどうかです。変数テンプレートtype_tagが、カテゴリに応じて別のクラスにリダイレクトされますか?だから私はこのようなものを想像:

template<???> 
constexpr auto type_tag = ????{}; 

//use with 'incomplete type' 
type_tag<std::tuple> //MetaTypeTag<std::tuple> 
//use with regular type 
type_tag<int> //TypeTag<int> 

私はすべての可能な方法を試みた - 再定義、明示的な特殊、部分的分業、オプションのテンプレートパラメータ、条件付使用して別名が、どれが働いていないし。私はC++ 17のtemplate<auto>が助けになると期待していましたが、1つは非タイプのものであることが判明しました。

+0

MetaTypeTagとTypeTagを統一すると、正確にはどういう意味ですか?あなたが期待していることの例を教えてください。 – linuxfever

+0

が編集されました。つまり、同じテンプレートクラスを使用するか、異なる表現を取得するために同じ式を使用することです。私はこれが専門化で解決できると思ったが、私は間違っていた。 – TheWisp

答えて

3

質問は、彼らが1つのテンプレートパラメータ

との両方の空のクラスですので、私はそう考えていない、struct MetaTypeTagstruct TypeTagを統一するどのような方法があるかどうかです。私はあなたのコード(非常に少ない)を少し簡単にするために想像できる 最善のオーバーロードconstexpr機能のいくつかを定義している、Tはタイプまたはテンプレートのいずれかですので、あなたがgetTag<T>()を呼び出すことができますgetTag()

template <typename T> 
auto constexpr getTag() 
{ return TypeTag<T>{}; } 

template <template <typename ...> typename T> 
auto constexpr getTag() 
{ return MetaTypeTag<T>{}; } 

を言います。

ので

constexpr auto combined_tag 
    = combine(getTag<std::tuple>(), getTag<int>(), getTag<float>()); 

を次のようにcombine()を呼び出すことができますしかし、私は大きな改善だとは思いません。

関連する問題