我有一个包含大量元素的 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/