For*_*oob 6 c++ template-meta-programming constexpr c++11
是否有任何例子,模板元编程比新的constexpr更好用?根据我的理解,constexpr和模板元编程都有类似的用途,但模板元编程并不过时.因此,必须有一些示例,其中模板元编程优于constexpr.对此有任何共同的想法将非常感谢,谢谢!
Man*_*726 10
constexpr以真正的C++函数形式提供对编译时计算的真正支持,而不是类似功能的基于模板的构造(元功能).所以部分答案是肯定的,因为 constexpr 在编译时计算方面胜过tmp ,至少在其语法上没有fp发起人们习惯于C++.请注意,我忽略了对编译器性能等的担忧.
另一方面,tmp仍然是相关的,实际上是在C++中进行类型计算的唯一方法.有一些新的方法来改进可怕的tmp语法,就像Boost.Hana对模板变量所做的那样.但是尽管有语法,仍然是一个与"普通"C++分离的功能元元语言.
从两个常见任务中你可能会问一个C++编译器(除了编译),根据你的要求使用类型系统按需生成新类型是constexpr无法实现的,只是因为这不是constexpr应该/设计做的事情.
有趣的是,模板不应该进行编译时计算.甚至元编程.它们被设计为通用编程的C++特性.但是你知道这个故事,90年代中期"Whoaaa C++模板完整!",表达模板和blitz ++之后,然后是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>>>
{};
Run Code Online (Sandbox Code Playgroud)
如您所见,此问题与类型有关.constexpr不应该做的事情.
关于挑战,Eric请路易迪安(Boost.Hana作者)和我common_type<Ts...>使用我们的库编写.上面的代码是Eric使用他的Meta库实现的.真诚的,我无法击败路易斯的折叠+也许monad解决方案:)