c++ - 使用模板函数和普通函数生成的代码之间的区别

标签 c++ compiler-construction templates code-generation

我有一个包含大量元素的 vector 。现在我想写一个小函数来计算 vector 中偶数或奇数元素的数量。由于性能是一个主要问题,我不想在循环中放置 if 语句。所以我写了两个小函数,比如:

long long countOdd(const std::vector<int>& v)
{
    long long count = 0;
    const int size = v.size();
    for(int i = 0; i < size; ++i)
    {
        if(v[i] & 1)
        {
            ++count;
        }
    }
    return count;
}

long long countEven(const std::vector<int>& v)
{
    long long count = 0;
    const int size = v.size();
    for(int i = 0; i < size; ++i)
    {
         if(0 == (v[i] & 1))
        {
            ++count;
        }
    }
    return count;
}

我的问题是我可以通过像这样编写一个模板函数来获得相同的结果吗:

template <bool countEven>
long long countTemplate(const std::vector<int>& v1)
{
    long long count = 0;
    const int size = v1.size();
    for(int i = 0; i < size; ++i)
    {
        if(countEven)
        {
            if(v1[i] & 1)
            {
                ++count;
            }
        }
        else if(0 == (v1[i] & 1))
        {
            ++count;
        }
    }
    return count;
}

像这样使用它:

int main()
{
  if(somecondition)
  {
     countTemplate<true>(vec); //Count even
  }      
  else
  {
     countTemplate<false>(vec); //Count odd
  } 
}

为模板和非模板版本生成的代码是否相同?还是会发出一些额外的指令?

请注意,数字的计数只是为了说明,因此请不要建议其他计数方法。

编辑: 行。我同意从性能的角度来看它可能没有多大意义。但至少从可维护性的角度来看,我希望只维护一个函数而不是两个。

最佳答案

模板化版本可能并且很可能由编译器在看到代码中的某个分支永远不会到达时进行优化。例如,countTemplate 代码会将 countEven 模板参数设置为 true,因此奇数分支将被切掉。

(抱歉,我忍不住建议另一种计数方法)

在这种特殊情况下,您可以在 vector 上使用 count_if:

struct odd { bool operator()( int i )const { return i&1; } };
size_t nbOdd = std::count_if( vec.begin(), vec.end(), odd() );

这也可以优化,并且写得更短 :) 标准库开发人员已经考虑了可能的优化,因此最好尽可能使用它,而不是编写自己的计数 for 循环。

关于c++ - 使用模板函数和普通函数生成的代码之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1299272/

相关文章:

c++ - 将Leap Motion Controller 与QT创建器一起使用

c++ - 有没有办法在我的通用功能路由器设计中支持 'const reference' 作为功能签名参数?

c++ - 我如何强制 C++ 从全局命名空间中选择一个函数?

c++ - 使用自定义服务器通过 http 安全传输数据

具有相同数据结构的 C++ 类

c++ - 从变量写入地址值?

c++ - 如何使用 g++ 创建具有特定名称的目标文件

java - 为什么javac的源码是用java写的?

c++ - 如何为 Windows 版 Mathematica 设置英特尔 C++ Composer XE?

c# - 创建和动态使用内容模板和控件