c – 避免在编译时错误条件下调用函数
我希望能够避免在条件为false时调用函数,这在编译时已知.现在我使用这样的东西:
template<bool Enabled> void fun(params) { //do nothing } template<> void fun<true>(params) { //do something with params. } 我不喜欢这种方法,即使函数体是空的,也会评估参数. 我想要一个解决方案,当根本没有调用该函数时,当条件为假时,不会对params进行求值(这可能在第一种情况下使用空函数进行优化,但我不能认为这是真的.编译器). 这甚至可能吗? 解决方法
是的.
template<bool b,typename Func,typename FuncElse> struct compile_time_if_functor { void operator()( Func&& f,FuncElse&& ) const{ std::forward<Func>(f)(); } }; template<typename Func,typename FuncElse> struct compile_time_if_functor<false,Func,FuncElse> { void operator()( Func&&,FuncElse&& else_f ) const{ std:forward<FuncElse>(else_f)(); } }; template<bool b,typename Else> void compile_time_if( Func&& f,Else&& elsef ) { compile_time_if_functor<b,Else> functor; functor( std::forward<Func>(f),std::forward<Else>(elsef) ); } template<bool b,typename Func> void compile_time_if( Func&& f ) { auto do_nothing = []{}; compile_time_if<b>( std::forward<Func>(f),std::move(do_nothing) ); } 使用: int main() { compile_time_if<expression>([&]{ // code that runs iff expression is true }); compile_time_if<expression2>([&]{ // code that runs iff expression2 is true },[&]{ // else clause,runs iff expression2 is false }); } 请注意,{}中的代码是编译的,但如果它位于if的错误分支中,则不会运行.因此,代码需要在类型级别上形成良好且合法,但在运行时执行并不一定合法.在这些lambda中没有创建大小为0的数组! 更高级的方法可以让你无限制地链接if-else块.如果我想这样做,我会使用命名运算符技巧. 首先,更改compile_time_if以返回std :: integral_constant< bool,b>. 然后,编写compile_time_else(Func&&)和compile_time_elseif< bool>(Func&&),它返回打包Func并覆盖operator *(std :: true_type,X)和operator *(std :: false_type,X)的类型)运行或不运行Func并返回std :: true_type或std :: false_type. 最终目标是这种语法: If<expression>([&]{ // block 1 })*Else([&]{ // block 2 }); If<expression>([&]{ // block 1 })*ElseIf<expression2>([&]{ // block 2 })*ElseIf<expression3>([&]{ // block 3 })*Else([&]{ // block 4 }); 允许全程级联流量控制.你甚至可以做到: compile_time_switch<value>( Case<c0,FallThrough>(),Case<c1>([&]{ // block 1 }),Case<c2,Continue>([&]{ // block 2 }),Case<c3>([&]{ // block 3 }),Case<c4>([&]->CanContinue{ // block 4 if (condition) { return Continue; } else { return Break; } }),Case<c4>([&]{ }),Default([&]{ }) }; 但那是领先于我们自己. 有关如何以允许编译器在编译时操作流控制的方式来复制C语法的想法,请查看boost phoenix.我只是把它包含在这里是为了完整性:实际上写这种东西并不是那么实用,因为一些可怜的草皮将不得不维护它,并且你最初几次写这些东西你将会做一份糟糕的工作! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |