C++ 使用C++;模板元编程
如何编写一个模板C++ 使用C++;模板元编程,c++,c++11,c++14,variadic-templates,template-meta-programming,C++,C++11,C++14,Variadic Templates,Template Meta Programming,如何编写一个模板meta_集,使meta_集::type`对于Ts的所有排列都是相同的 换句话说,只要参数列表是相同的,无论顺序如何,我们都希望使用相同的meta_set::type,也就是说,当作为一个集合(或多集合,如果更容易的话) 比如说, std::is_same< meta_set<int,double,string>::type, meta_set<double,string,int>::type >::value == true std::is
meta_集
,使meta_集::type`对于Ts的所有排列都是相同的
换句话说,只要参数列表是相同的,无论顺序如何,我们都希望使用相同的meta_set::type
,也就是说,当作为一个集合(或多集合,如果更容易的话)
比如说,
std::is_same< meta_set<int,double,string>::type, meta_set<double,string,int>::type >::value == true
std::is_same< meta_set<int,double,string>::type, meta_set<double,string,bool>::type >::value == false
std::is_same::value==true
std::is_same::value==false
当您希望每个模板参数集都有一个模板实例化时,这可能会很方便
注意:这不是一个家庭作业,而是我在工作中处理大量模板代码时感到好奇的事情。我不是元编程专家,所以我想也许人们可以分享他们的知识 规范化表示一组类型的唯一可行方法是使用排序列表(或可以转换为排序列表的东西,例如二进制搜索树)。但是C++中没有类型的自然编译时间排序,所以没有什么排序。 <> > C++应该要求<代码> STD::Type:No::在 >代码> CONTXPROP>代码>,或定义一个具有类似功能的模板,比如<>代码> STD::在之前,它将创建类型之间的全局静态排序,从而可以创建规范有序的列表。遗憾的是,情况并非如此
由于缺少编译器支持的排序,程序员必须为每一对可能的类型定义自己的
is_pre
,这当然不是每一对类型都可能做到的,但只适用于某些有限的已知预先集。规范化表示一组类型的唯一可行方法是使用排序列表(或者可以转换成排序列表的东西,例如二进制搜索树),但是C++中没有类型的自然编译时间排序,所以没有什么排序。
<> > C++应该要求<代码> STD::Type:No>:在 >代码> COSTEXPRO< /COD>,或者定义一个具有类似功能的模板,例如<>代码> STD::在之前,它将创建类型之间的全局静态排序,这将使得创建规范有序列表成为可能。
由于缺少编译器支持的排序,程序员必须为每一对可能的类型定义自己的
is_\u,这当然不可能对每一对类型都这样,但只能对一些有限的已知预先设置进行定义。无法在编译时对所有类型进行全局排序;访问typeid(T)之类的内容(typeid(U))
不是constepr
。因此不能将两个任意meta\U集
和meta\U集
设置为同一类型,因为不能排序
如果类型不相同,则无法修改std::is_same
的行为以返回true。任何试图这样做的代码(例如通过专门化std::is_same
)都将违反std::is_same
的要求,这将导致程序格式错误,无需诊断
如果将类型集限制为所有类型的某个子集,则可以执行此操作。最简单的方法是使用集中列表:
template<class...T>
struct types_t {};
using global_order = types_t<int, double, std::string>;
一旦写下:
template<class...Ts>
using meta_set = typename type_sorter< types_t<Ts...> >::type;
这就像是std::is_same
,除非fedmeta_集
s会检查它们是否具有相同的内容,而不是寻找严格的类型相等。但是,您的评论提到这不是您的实际问题,而是您正在谈论将meta_集
参数传递到不同的模板d希望它们按规范顺序排列。在编译时无法全局排序所有类型;访问诸如typeid(T)之类的东西。在(typeid(U))
之前,不可将两个任意的meta_set
和meta设置为同一类型,因为您无法排序
如果类型不相同,则无法修改std::is_same
的行为以返回true。任何试图这样做的代码(例如通过专门化std::is_same
)都将违反std::is_same
的要求,这将导致程序格式错误,无需诊断
如果将类型集限制为所有类型的某个子集,则可以执行此操作。最简单的方法是使用集中列表:
template<class...T>
struct types_t {};
using global_order = types_t<int, double, std::string>;
一旦写好:
template<class...Ts>
using meta_set = typename type_sorter< types_t<Ts...> >::type;
这就像是std::is_same
,除非fedmeta_集
s会检查它们是否具有相同的内容,而不是寻找严格的类型相等。但是,您的评论提到这不是您的实际问题,而是您正在谈论将meta_集
参数传递到不同的模板我的想法不是对类型进行排序,而是检查第一个元集中的类型是否出现在第二个元集中
template <typename... Args>
struct TypeList;
template <typename Head, typename... Tail>
struct TypeList<Head, Tail...>
{
using TailList = TypeList<Tail...>;
using HeadType = Head;
static_assert(!TailList::template contains<Head>(), "Types must be unique");
static constexpr int size()
{
return 1 + TailList::size();
}
template <typename Type>
static constexpr bool contains()
{
return std::is_same<Head, Type>::value || TailList::template contains<Type>();
}
};
template<>
struct TypeList<>
{
static constexpr int size()
{
return 0;
}
template <typename Type>
static constexpr bool contains()
{
return false;
}
};
template <typename ListLhs, typename ListRhs>
struct IsSame
{
static constexpr bool value()
{
return ListLhs::size() == ListRhs::size() && valueImpl();
}
static constexpr bool valueImpl()
{
return ListLhs::template contains<typename ListRhs::HeadType>() &&
IsSame<ListLhs,typename ListRhs::TailList>::valueImpl();
}
};
template <typename ListLhs>
struct IsSame<ListLhs, TypeList<>>
{
static constexpr bool value()
{
return false;
}
static constexpr bool valueImpl()
{
return true;
}
};
template <>
struct IsSame<TypeList<>, TypeList<>>
{
static constexpr bool value()
{
return true;
}
static constexpr bool valueImpl()
{
return false;
}
};
struct MyStruct{};
using Types = TypeList<int, bool, char, MyStruct, double>;
using TypesSame = TypeList<int, MyStruct, bool, char, double>;
using LessTypes = TypeList<int, bool, char>;
using EmptyTypes = TypeList<>;
static_assert(IsSame<Types, TypesSame>::value(), "Underlying types should be the same");
static_assert(!IsSame<Types, LessTypes>::value(), "Less types");
static_assert(!IsSame<Types, EmptyTypes>::value(), "Not the same as Empty");
static_assert(IsSame<EmptyTypes, EmptyTypes>::value(), "Empty types");
模板
结构类型表;
模板
结构类型表
{
使用TailList=类型列表;
使用头型=头;
静态断言(!TailList::template contains(),“类型必须唯一”);
静态constexpr int size()
{
返回1+TailList::size();
}
模板
静态constexpr bool contains()
{
return std::is|u same::value | | TailList::template contains();
}
};
模板
结构类型表
{
静态constexpr int size()
{
返回0;
}
模板
静态constexpr bool contains()
{
返回false;
}
};
模板
结构名称
{
静态constexpr布尔值()
{
返回ListLhs::size()==ListRhs::size()&&valueImpl();
}
静态constexpr bool valueImpl()
{
return ListLhs::template contains()&&
IsName::valueImpl();
}
};
模板
结构名称
{
静态constexpr布尔值()
{
返回false;
}