簡體   English   中英

避免在編譯時錯誤條件下調用函數

[英]Avoid function call on compile time false condition

我希望能夠避免在條件為false時調用函數,這在編譯時已知。 現在我使用這樣的東西:

template<bool Enabled>
void fun(params)
{
    //do nothing
}

template<>
void fun<true>(params)
{
    //do something with params.
}

我不喜歡這種方法,即使函數體是空的,也會評估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 Func, typename Else>
void compile_time_if( Func&& f, Else&& elsef ) {
  compile_time_if_functor<b, Func, 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_typestd::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。 我只是把它包含在這里是為了完整性:實際上寫這種東西並不是那么實用,因為一些可憐的草皮將不得不維護它,並且你最初幾次寫這些東西你將會做一份糟糕的工作!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM