假设我们有一个功能
template< typename A, typename B, typename C >
void function(vector<A>& keyContainer, int a, int b, int c, boost::function<bool(B&)> selector, C* objPointer = NULL)
{
BOOST_FOREACH(const A& key, keyContainer)
{
B* pVal = someGetObjFunction(objPointer, key);
if(pVal)
{
if(selector && selector(*pVal))
{
pVal->someOtherFunction(1,2,3);
}
//some more code
}
}
}
这看起来很糟糕,因为它总是会进入
if(selector && selector(*pVal))
即使它是NULL,一个明显的解决方法是:
template< typename A, typename B, typename C >
void function(vector<A>& keyContainer, int a, int b, int c, boost::function<bool(B&)> selector, C* objPointer = NULL)
{
if(selector)
{
BOOST_FOREACH(const A& key, keyContainer)
{
B* pVal = someGetObjFunction(objPointer, key);
if(pVal)
{
if(selector(*pVal))
{
pVal->someOtherFunction(1,2,3);
}
//some more code
}
}
}
else
{
BOOST_FOREACH(const A& key, keyContainer)
{
B* pVal = someGetObjFunction(objPointer, key);
if(pVal)
{
pVal->someOtherFunction(1,2,3);
//some more code
}
}
}
}
但是这导致了大量的代码重复,另一种方法是在函数为NULL的情况下对这种情况进行专门化,但不会像上面的例子那样几乎相同吗?有没有其他方法可以做到这一点而不重复所有代码?
答案 0 :(得分:1)
您的问题描述有点令人困惑。您没有检查NULL,因为selector
不是指针。相反,您正在检查boost::function
对象是否为empty()
,请参阅:http://www.boost.org/doc/libs/1_55_0/doc/html/boost/function.html#idp54857000-bb。
此外,您的两个代码块不相同。如果 (选择器提供和 true)或(未提供选择器),您似乎表示要执行内部循环。
所以,你的第一个代码块应该是:
template< typename A, typename B, typename C >
void function(vector<A>& keyContainer, int a, int b, int c, boost::function<bool(B&)> selector, C* objPointer = NULL)
{
BOOST_FOREACH(const A& key, keyContainer)
{
B* pVal = someGetObjFunction(objPointer, key);
if(pVal)
{
if(!selector || (selector && selector(*pVal)))
{
pVal->someOtherFunction(1,2,3);
}
//some more code
}
}
}
这在逻辑上等同于您的第二个代码块。
正如Igor Tendetnik所提到的,您需要实际测量代码以查看瓶颈所在。它可能不是检查选择器是否为空。
如果检查选择器是否为空确实是你的瓶颈,这是不太可能的,因为打开优化的编译器会使这些比较非常快速的内联函数调用,你可以缓存空测试的结果。 / p>
template< typename A, typename B, typename C >
void function(vector<A>& keyContainer, int a, int b, int c, boost::function<bool(B&)> selector, C* objPointer = NULL)
{
bool check_selector = !selector.empty();
BOOST_FOREACH(const A& key, keyContainer)
{
B* pVal = someGetObjFunction(objPointer, key);
if(pVal)
{
if(!check_selector || (check_selector && selector(*pVal)))
{
pVal->someOtherFunction(1,2,3);
}
//some more code
}
}
}