c – 懒惰评估(短路)模板条件类型的通用方式
发布时间:2020-12-16 05:52:37 所属栏目:百科 来源:网络整理
导读:当使用编译时字符串(charable char)的操作时,我需要实现一种检查编译时字符串是否包含另一个(较小的)编译时字符串的方法. 这是我的第一个尝试: templateint I1,int I2,typename,typename struct Contains;templateint I1,char... Cs1,char... Cs2 struct Co
当使用编译时字符串(charable char)的操作时,我需要实现一种检查编译时字符串是否包含另一个(较小的)编译时字符串的方法.
这是我的第一个尝试: template<int I1,int I2,typename,typename> struct Contains; template<int I1,char... Cs1,char... Cs2> struct Contains<I1,I2,CharList<Cs1...>,CharList<Cs2...>> { using L1 = CharList<Cs1...>; using L2 = CharList<Cs2...>; static constexpr int sz1{L1::size}; static constexpr int sz2{L2::size}; using Type = std::conditional < (I1 >= sz1),std::false_type,std::conditional < (L1::template at<I1>() != L2::template at<I2>()),typename Contains<I1 + 1,L1,L2>::Type,std::conditional < (I2 == sz2 - 1),std::true_type,I2 + 1,L2>::Type > > >; }; 我发现这个解决方案非常容易阅读和理解.不幸的是,它不工作. 编译器总是尝试实例化std :: conditional的每个单独的分支,即使那些不被采用的分支.换句话说,短路没有发生. 这使得包含无限地被实例化. 我解决了我的原始问题,将每个std ::条件块分隔在单独的模板类中,其中条件结果作为部分专业化处理. 它的工作原理,但不幸的是我觉得很难阅读/修改. 有没有办法懒惰地实例化一个模板类型并且接近我的原始解决方案? 这是代码可能是什么样的示例: using Type = std::conditional < (I1 >= sz1),std::conditional < (L1::template at<I1>() != L2::template at<I2>()),DeferInstantiation<typename Contains<I1 + 1,L2>::Type>,std::conditional < (I2 == sz2 - 1),L2>::Type> > > >; 是否可以实现DeferInstantiation< T? 解决方法
这是一个通用模板,允许延迟实例化,只是不实例化:)
template <bool B,template <typename...> class TrueTemplate,template <typename...> class FalseTemplate,typename ArgsTuple> struct LazyConditional; template <template <typename...> class TrueTemplate,typename ... Args> struct LazyConditional<true,TrueTemplate,FalseTemplate,std::tuple<Args...>> { using type = TrueTemplate<Args...>; }; template <template <typename...> class TrueTemplate,typename ... Args> struct LazyConditional<false,std::tuple<Args...>> { using type = FalseTemplate<Args...>; }; 为了完整,一个简单的例子展示了它的用途: #include <iostream> #include <type_traits> #include <tuple> template <typename T> struct OneParam { void foo(){std::cout << "OneParam" << std::endl;} }; template <typename T,typename U> struct TwoParam { void foo(){std::cout << "TwoParam" << std::endl;} }; template <bool B,std::tuple<Args...>> { using type = FalseTemplate<Args...>; }; template <typename ... Args> struct OneOrTwoParam { using type = typename LazyConditional<sizeof...(Args)==1,OneParam,TwoParam,std::tuple<Args...> >::type; }; int main() { OneOrTwoParam<int>::type().foo(); OneOrTwoParam<int,int>::type().foo(); return 0; } 打印: OneParam TwoParam (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |