Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ constexpr上的模板元编程示例?_C++_C++11_Template Meta Programming_Constexpr - Fatal编程技术网

C++ constexpr上的模板元编程示例?

C++ constexpr上的模板元编程示例?,c++,c++11,template-meta-programming,constexpr,C++,C++11,Template Meta Programming,Constexpr,有没有比新的constexpr更好地使用模板元编程的例子?据我所知,constexpr和模板元编程都有类似的用途,但模板元编程并不是过时的。因此,必须有一些例子表明,模板元编程优于constexpr。如果您对此有任何共同的想法,我们将不胜感激,谢谢 CONTXPRP提供了真正C++函数形式的编译时计算的真正支持,而不是像模板化的构造(元函数)那样的功能。因此,部分答案是 >是/强>在编译时计算中,ToStRePrExpRPR击败TMP ,至少在其语法上没有FP启动的人用于C++。请注意,我忽略

有没有比新的constexpr更好地使用模板元编程的例子?据我所知,constexpr和模板元编程都有类似的用途,但模板元编程并不是过时的。因此,必须有一些例子表明,模板元编程优于constexpr。如果您对此有任何共同的想法,我们将不胜感激,谢谢

<代码> CONTXPRP</CUT>提供了真正C++函数形式的编译时计算的真正支持,而不是像模板化的构造(元函数)那样的功能。因此,部分答案是<强> >是/强>在编译时计算中,ToStRePrExpRPR击败TMP <强>,至少在其语法上没有FP启动的人用于C++。请注意,我忽略了编译器性能等方面的问题

另一方面,tmp仍然是相关的,实际上是唯一的方法,用C++进行类型计算。有新的方法可以改进糟糕的tmp语法,比如Boost.Hana对模板变量的处理。但是,尽管有语法,它仍然是一个与“正常”C++分离的功能元语言。 关于类型计算

从两个常见的任务中,您可以要求C++编译器(除了编译),根据需要来播放根据需求生成新类型的类型系统,这是CONTXPR无法实现的,仅仅因为这不是CONTXPR的假设/设计要做的。p> 有趣的是,模板也不应该进行编译时计算。甚至元编程。它们被设计为泛型编程的C++特征。但你知道的故事,90年代中期“WoaaaC++模板是图灵完成!”,表达模板和闪电+ +后,然后Alexandrescu和他的洛基。现在我们有了

和一个严肃的提议

考虑以下示例(不是我的,取自Eric Niebler):编写一个实用程序,为您提供一组类型之间的通用类型:

namespace m = ranges::meta; 
namespace ml = ranges::meta::lazy; 

template<typename T, typename U> 
using builtin_common_t = 
    decltype(true? std::declval<T>() : std::declval<U>()); 
template<typename T, typename U> 
using lazy_builtin_common_t = 
    m::defer<builtin_common_t, T, U>; 

template<typename...Ts> 
struct common_type 
{}; 

template<typename ...Ts> 
using common_type_t = m::eval<common_type<Ts...>>; 

template<typename T> 
struct common_type<T> 
  : std::decay<T> 
{}; 

template<typename T, typename U> 
struct common_type<T, U> 
  : m::if_c< 
        ( std::is_same<decay_t<T>, T>::value && 
          std::is_same<decay_t<U>, U>::value ), 
        ml::let<lazy_builtin_common_t<T, U>>, 
        common_type<decay_t<T>, decay_t<U>>> 
{}; 

template<typename T, typename U, typename... Vs> 
struct common_type<T, U, Vs...> 
  : ml::let<ml::fold<m::list<U, Vs...>, T, m::quote<common_type_t>>> 
{}; 
名称空间m=ranges::meta;
名称空间ml=ranges::meta::lazy;
模板
使用内置\u公共\u t=
decltype(true?std::declval():std::declval());
模板
使用lazy\u内置\u公共\u t=
m::延迟;
模板
结构公共类型
{}; 
模板
使用公共类型\u t=m::eval;
模板
结构公共类型
:std::衰变
{}; 
模板
结构公共类型
:m::如果
(标准::是否相同::值和
std::值是否相同,
让我们,
常见类型>
{}; 
模板
结构公共类型
:ml::let
{}; 
正如您所看到的,这个问题与类型有关。constexpr不应该做的事情


关于挑战,Eric要求Louis Dionne(Boost.Hana作者)和我使用我们的库编写
common_type
。上面的代码是Eric使用他的元库实现的。诚恳地说,我无法击败Louis的fold+maybe monad解决方案:)

无论何时,只要你想创建一套相关的类型,它们只在其中使用的一些类型上有所不同。仅使用
constexpr
如何实现
std::vector


不过,模板和constexpr执行不同的作业。不过,这些案例并非详尽无遗。

您打算如何实现,编译时多态性与
constexpr
?相关:我认为你寻找示例的措辞让人们觉得这是离题的,而你真正想做的是理解何时需要tmp,而constexpr不是选项。你的第一段基本上是论点Sumant Tambe。。我很好奇,你有没有一个例子可以适用于什么时候需要tmp的典型SO答案?@ShafikYaghmour就我而言,从编译器的角度来看,constexpr比普通模板递归实例化更昂贵。实际上,constexpr的默认最大递归限制远小于tmp限制。另一方面,C++14 constexpr允许循环。因此,几乎从不需要rec。@ShafikYaghmour所以答案可能是:使用constexpr进行编译时计算。关键是几乎没有人进行纯编译时计算,而是使用类型。而constexpr与此无关。你能就这个问题详细介绍一下类型计算吗?在讨论是否更喜欢模板元编程而不是constexpr时,这意味着什么?这是一个非常好的答案,谢谢@当然,给我一点时间我想OP谈论的是模板元编程和
constexpr
,而不是模板的一般用途。即使模板机制在幕后生成代码,这也是一种元编程,你完全知道这个社区是什么样的TMP:有简单的模板,如美化的Java泛型(这是C++程序员的90%个C++模板),并且有复杂的类型,其中计算类型、生成新类、做复杂的专业化、特征等(TMP,C++ java的模板)。我的意思是OP询问了TMP,询问了TMP的一般定义。也许你是对的,不是正确的TMP def,但仍然是人们所理解的TMP。请记住,人们将来会阅读这个主题,谈论TMP==模板可能会误导他们。这是不正确的,我们应该适当地讨论tmp吗?那是一个完全不同的话题。这是一个有趣的话题,值得在这里提出一个问题,我想也许我错了,但我理解
std::vector
代码不是元编程,而是通用编程。当我使用
std::vector
时,实例化有一个元编程部分——编译器实例化处理通用代码。在这方面,我同意你们的观点——每次使用模板时,都有一个元编程部分。无论如何,我认为这是一次很好的讨论。谢谢,伙计们,很抱歉你们这么想。