c++ std::conditional 惰性求值
值得记录一下,加深了我对模板推导的理解
首先std::conditional不是惰性求值的,在模板元编程里面有时候不能对不正确的参数求值
#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
template<ll val>
struct loop : loop<val - 1>
{
using type = integral_constant<ll,-1>;
};
template<typename T>
struct test
{
using type = typename std::conditional<is_same<T,true_type>::value,
loop<0>::type,
integral_constant<ll,10>
>::type;
};
int main()
{
cout << test<false_type>::type::value;
return 0;
}
首先loop<0>是个死循环,这个代码逻辑上是没有问题的,但是因为conditional不是惰性求值的问题,编译器会尝试推导loop<0>的类型
解决办法就是加一个间接层
#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
template<ll val>
struct loop : loop<val - 1>
{
using type = integral_constant<ll,-1>;
};
template<ll val>
struct late
{
using type = typename loop<val>::type;
};
template<typename T>
struct test
{
using type = typename std::conditional<is_same<T,true_type>::value,
late<0>,
integral_constant<ll,10>
>::type::type;
};
int main()
{
cout << test<false_type>::type::value;
return 0;
}
编译器只会推导late这个包装层的类型,这个是可以确定的,注意conditional<,,>::type::type
integral_constant::type指向自己的类型,而late这个包装类的type指向loop<0>
这样就可以实现惰性求值,可以简化一些模板元编程的代码
深入的原理还需要看《c++ Templates》
感觉比较有趣,Stack Overflow中也有这个问题的答案,不过写的比较凌乱,这两个代码一对比,读者应该能清晰的看到这个博文的意义在哪里
本文来自博客园,作者:XDU18清欢,转载请注明原文链接:https://www.cnblogs.com/XDU-mzb/p/14959454.html
浙公网安备 33010602011771号