避免if语句在for循环中? [英] Avoiding if statement inside a for loop?

查看:135
本文介绍了避免if语句在for循环中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 Writer 的类,具有 writeVector 的函数:

  void Drawer :: writeVector(vector< T> vec,bool index = true)
{
for(unsigned int i = 0 ; i< vec.size(); i ++){
if(index){
cout< i<< \t;
}
cout<< vec [i] \\\
;
}
}



我试图不要有重复的代码,同时仍然担心性能。
在函数中,我对的每个回合执行 if(index)检查 - 循环,即使结果总是相同的。
这是针对担心性能。



我可以通过将 code> -loop。
但是,我会收到重复的代码:

  void Drawer :: writeVector b $ b {
if(index){
for(...){
cout< i<< \t<< vec [i] \\\
;
}
}
else {
for(...){
cout< vec [i] \\\
;
}
}
}

解决方案。
我一直在想,是两个私人函数,其中一个超出索引,然后调用另一个。
另一个只输出值。
然而,我不知道如何使用它与我的程序,我仍然需要如果检查哪一个调用...



根据问题,多态性似乎是一个正确的解决方案。
但我不能看到我应该如何使用它。
解决这种问题的首选方法是什么?



这不是一个真正的程序,我只是想学习如何这种问题应该解决。

解决方案

将循环体作为函子。它在编译时内联,没有性能损失。



传递各种变化的想法在C ++标准库中是无所不在的。



如果你允许使用C ++ 11,你可以这样做:

  #include< iostream> 
#include< set>
#include< vector>

template< typename Container,typename Functor,typename Index = std :: size_t>
void for_each_indexed(const Container& c,Functor f,Index index = 0){

for(const auto& e:c)
f(index ++,e);
}

int main(){

using namespace std;

set< char> s {'b','a','c'};

//从1而不是0开始的索引
for_each_indexed(s,[](size_t i,char e){cout<< i<'\t' < e<<'| \ n';},1u);

cout<< -----<< endl;

vector< int> v {77,88,99};

//无索引
for_each_indexed(v,[](size_t,int e){cout<<<'; \ n';}
}

这段代码不是完美的,但你能想到。



在旧的C ++ 98中,它看起来像这样:

  #include< iostream> ; 
#include< vector>
using namespace std;

struct with_index {
void operator()(ostream& out,vector< int> :: size_type i,int e){
out< i<< '\t'<< e - < '\\\
';
}
};

struct without_index {
void operator()(ostream& out,vector< int> :: size_type i,int e){
out< e - < '\\\
';
}
};


template< typename Func>
void writeVector(const vector< int>& v,Func f){
for(vector< int> :: size_type i = 0; i< v.size(); ++ i)
f(cout,i,v [i]);
}
}

int main(){

vector< int> v;
v.push_back(77);
v.push_back(88);
v.push_back(99);

writeVector(v,with_index());

cout<< -----<< endl;

writeVector(v,without_index());

return 0;
}

再次,代码远非完美,但它给了你想法。 / p>

I have a class called Writer that has a function writeVector like so:

void Drawer::writeVector(vector<T> vec, bool index=true)
{
    for (unsigned int i = 0; i < vec.size(); i++) {
        if (index) {
            cout << i << "\t";
        }
        cout << vec[i] << "\n";
    }
}

I'm trying not to have a duplicate code, while still worrying about the performance. In the function, I'm doing the if (index) check on every round of my for-loop, even though the result is always the same. This is against "worrying about the performance".

I could easily avoid this by placing the check outside of my for-loop. However, I'll get loads of duplicate code:

void Drawer::writeVector(...)
{
    if (index) {
        for (...) {
            cout << i << "\t" << vec[i] << "\n";
        }
    }
    else {
        for (...) {
            cout << vec[i] << "\n";
        }
    }
}

So these are both "bad" solutions for me. What I've been thinking, is two private functions, one of them outs the index and then calls the other. The other one only outs the value. However, I can't figure out how to use it with my program, I'd still need the if check to see which one to call...

According to the problem, polymorphism seems like a correct solution. But I can't see how should I use it here. What would be the preferred way to solve this kind of problem?

This is not a real program, I'm just interested in learning how this kind of problem should be solved.

解决方案

Pass in the body of the loop as a functor. It gets inlined at compile-time, no performance penalty.

The idea of passing in what varies is ubiquitous in the C++ Standard Library. It is called the strategy pattern.

If you are allowed to use C++11, you can do something like this:

#include <iostream>
#include <set>
#include <vector>

template <typename Container, typename Functor, typename Index = std::size_t>
void for_each_indexed(const Container& c, Functor f, Index index = 0) {

    for (const auto& e : c)
        f(index++, e);
}

int main() {

    using namespace std;

    set<char> s{'b', 'a', 'c'};

    // indices starting at 1 instead of 0
    for_each_indexed(s, [](size_t i, char e) { cout<<i<<'\t'<<e<<'\n'; }, 1u);

    cout << "-----" << endl;

    vector<int> v{77, 88, 99};

    // without index
    for_each_indexed(v, [](size_t , int e) { cout<<e<<'\n'; });
}

This code is not perfect but you get the idea.

In old C++98 it looks like this:

#include <iostream>
#include <vector>
using namespace std;

struct with_index {
  void operator()(ostream& out, vector<int>::size_type i, int e) {
    out << i << '\t' << e << '\n';
  }
};

struct without_index {
  void operator()(ostream& out, vector<int>::size_type i, int e) {
    out << e << '\n';
  }
};


template <typename Func>
void writeVector(const vector<int>& v, Func f) {
  for (vector<int>::size_type i=0; i<v.size(); ++i) {
    f(cout, i, v[i]);
  }
}

int main() {

  vector<int> v;
  v.push_back(77);
  v.push_back(88);
  v.push_back(99);

  writeVector(v, with_index());

  cout << "-----" << endl;

  writeVector(v, without_index());

  return 0;
}

Again, the code is far from perfect but it gives you the idea.

这篇关于避免if语句在for循环中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆