constexpr上的模板元编程示例
Examples on template metaprogramming over constexpr?
有没有比新的constexpr更适合使用模板元编程的例子?据我所知,constexpr和模板元编程都有相似的目的,但模板元编程并没有过时。因此,必须有一些例子表明,模板元编程比constexpr更受欢迎。如果您对此有任何共同的想法,我们将不胜感激,谢谢!
constexpr
以真正的C++函数的形式为编译时计算提供了真正的支持,而不是像基于模板的构造(元函数)那样的函数。因此,部分答案是是constexpr在编译时计算上胜过tmp,至少在它的语法上,对于习惯C++的非fp启动的人来说是这样。注意,我忽略了对编译器性能等的担忧。
另一方面,tmp仍然是相关的,实际上是在C++中进行类型计算的唯一方法。有一些新的方法可以改进糟糕的tmp语法,就像Boost.Hana对模板变量所做的那样。但尽管有语法,它仍然是一种与"正常"C++分离的函数元语言。
关于类型计算
从你可能要求C++编译器完成的两个常见任务中(除了编译),玩类型系统根据你的需求生成新类型是constexpr无法实现的,因为这不是constexpr应该/设计的目的。
有趣的是,模板不应该进行编译时计算。甚至元编程。它们被设计为用于通用编程的C++特性。但你知道这个故事,90年代中期"Whoaaa C++模板正在变得完整!",表达式模板和闪电战++之后,然后是Alexandrescu和他的Loki。现在我们有了<type_traits>
和一个在中有一个成熟的元编程库的严肃建议。
考虑这个例子(不是我的,取自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>>>
{};
正如您所看到的,这个问题是关于类型的。constexpr不应该做的事情。
关于这个挑战,Eric要求Louis Dionne(Boost.Hana的作者)和我使用我们的库编写common_type<Ts...>
。上面的代码是Eric使用他的元库实现的。真诚地说,我无法击败Louis的折叠+也许是monad解决方案:)
无论何时,只要您想创建一套相关类型,而这些类型只在其中使用的某些类型上有所不同,就可以直接创建。如果只有constexpr
,您将如何实现std::vector<T>
?
Templates和constexpr
执行不同的作业,尽管在某些情况下,旧的模板实现可能会被constexpr
替换为更简洁的版本。不过,这些案例并非详尽无遗。
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 多成员Constexpr结构初始化
- 条件constexpr函数
- 有一个打印语句的函数是一种糟糕的编程实践吗
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- Visual C++ constexpr Hints
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 为什么constexpr的性能比正常表达式差
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 为什么std::isnan 不是 constexpr?
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 使用 constexpr 或模板元编程简化较长的展开循环表达式
- 是否可以以编程方式初始化 constexpr std::array 成员
- constexpr上的模板元编程示例
- C++11 constexpr到过时的模板元编程
- 使用constexpr或struct进行元编程
- 打印类型包括装饰,模板元编程,constexpr,使用什么