避免基于作为模板参数的函数的返回值的分支 [英] Avoiding branching based on the return value of the function that is a template argument
问题描述
假设以下策略类照顾算法的一个方面:
struct VoidF {
static void f(){
... //有副作用的代码
}
};
struct BoolF {
static bool f(){
bool res = ...; //一些计算
return res;
}
};
BoolF
政策是 :当BoolF :: f()返回 true
时,算法可以退出。 VoidF
是增强 - 不知道,因此它返回 void
(我不想强迫用户的
该算法目前是这样编写的: bool
模板< typename F>
struct算法{
void run(){
... //这里的计算
if(std :: is_same if(F :: f())return;
} else
F :: f(); //如果F是VoidF,应该没有分支和
//编译器优化将被启用
... //更多的计算,除非F :: f()摆脱of it
}
};
当然,如果 Algorithm
用 VoidF
实例化。有没有办法解决这个问题,应该没有分支在算法< VoidF> :: run()
如注释所示?
您应该在运行时使用SFINAE而不是分支。
你的函数运行应该看起来像这样:
template< typename F>
struct算法{
void run(){
... //这里的一些计算
doRun();
}
template< std :: enable_if_t< std :: is_same< decltype(F :: f()),bool> :: value,int& = 0>
void doRun(){
if(F :: f()){
//如果需要,做更多的计算,或者简单地删除if和返回
}
}
template< std :: enable_if_t<!std :: is_same< decltype(F :: f()),bool> :: value,int& = 0>
void doRun(){
F :: f();
... //更多的计算,除非F :: f()摆脱它
}
};
Suppose the following policy classes that take care of one aspect of an algorithm:
struct VoidF {
static void f() {
... // some code that has side effects
}
};
struct BoolF {
static bool f() {
bool res = ...; // some computation
return res;
}
};
The BoolF
policy is "enhancement-aware": when BoolF::f() returns true
, the algorithm can exit. VoidF
is "enhancement-unaware", hence it returns void
(I don't want to force the user of my library to return bool
when it does not mean anything to him).
The algorithm is currently written like this:
template <typename F>
struct Algorithm {
void run() {
... // some computation here
if (std::is_same<decltype(F::f()), bool>::value) {
if (F::f()) return;
} else
F::f(); // If F is VoidF, there should be no branching and some
// compiler optimizations will be enabled
... // more computation, unless F::f() got rid of it
}
};
Of course, this does not work if Algorithm
is instantiated with VoidF
. Is there a way to fix this in a way that there should be no branching in Algorithm<VoidF>::run()
as indicated by the comment?
You should use SFINAE instead of branching at runtime.
You function run should look like this:
template <typename F>
struct Algorithm {
void run() {
... // some computation here
doRun();
}
template<std::enable_if_t<std::is_same<decltype(F::f()), bool>::value, int> = 0>
void doRun() {
if (F::f()) {
// do some more computations if needed or simply remove the if and return
}
}
template<std::enable_if_t<!std::is_same<decltype(F::f()), bool>::value, int> = 0>
void doRun() {
F::f();
... // more computation, unless F::f() got rid of it
}
};
这篇关于避免基于作为模板参数的函数的返回值的分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!