c++ - 优化循环并避免模板特化中的代码重复

标签 c++ loops templates optimization 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
        }
    }
}

关于c++ - 优化循环并避免模板特化中的代码重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25340338/

相关文章:

c++ - 将数据从txt文件复制到C++中的char指针

java - For循环转换While循环

PHP - foreach 循环带有条件,无需额外的内部 IF 语句

templates - 如何从 template.FuncMap 返回 HTML 模板?

c++ - 根据一些枚举值在编译时添加额外的方法

c++ - 如何使用 Meego Touch Framework 创建 QT 插件?

c++ - unordered_map 会是一个不错的选择吗?

循环内的 JavaScript 闭包 – 简单的实际示例

c++模板enable_if无法将函数定义与现有声明匹配

c++ - OpenGL 应用程序在其他计算机上崩溃