[英]Optimizing loop and avoiding code duplication in a template specialization
假設我們有一個功能
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的情況進行特殊化處理,但是否與上面的示例幾乎相同? 還有另一種方式可以做到,而無需復制所有代碼嗎?
您的問題描述有點混亂。 您沒有檢查NULL,因為selector
不是指針。 相反,您要檢查boost::function
對象是否為empty()
請參見: http : //www.boost.org/doc/libs/1_55_0/doc/html/boost/function.html#idp54857000-bb 。
另外,您的兩個代碼塊也不相同。 你似乎表明您要執行的內循環,如果(提供和真實的選擇) 或者 或 (不提供選擇)。
因此,您的第一個代碼塊應為:
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所提到的,您需要實際測量代碼以查看瓶頸所在。 可能不是檢查選擇器是否為空。
如果檢查選擇器是否確實是您的瓶頸,這不太可能,因為啟用了優化的編譯器將使這些比較非常快速地進行內聯函數調用,因此可以緩存空測試的結果。
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
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.