[英]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_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。 我只是把它包含在這里是為了完整性:實際上寫這種東西並不是那么實用,因為一些可憐的草皮將不得不維護它,並且你最初幾次寫這些東西你將會做一份糟糕的工作!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.