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

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

问题描述

我有一个名为 Writer 的类,它有一个函数 writeVector 像这样:

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 << "	";
        }
        cout << vec[i] << "
";
    }
}

我正在努力避免重复代码,同时仍然担心性能.在函数中,我正在对 for 循环的每一轮进行 if (index) 检查,即使结果始终相同.这反对担心性能".

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".

通过将检查放在我的 for 循环之外,我可以轻松避免这种情况.但是,我会收到大量重复代码:

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 << "	" << vec[i] << "
";
        }
    }
    else {
        for (...) {
            cout << vec[i] << "
";
        }
    }
}

所以这些对我来说都是糟糕"的解决方案.我一直在想的是两个私有函数,其中一个超出索引,然后调用另一个.另一个只是超出了价值.但是,我不知道如何在我的程序中使用它,我仍然需要 if 检查以查看调用哪个...

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?

这不是真正的程序,我只是想了解如何解决此类问题.

推荐答案

作为函子传入循环体. 它在编译时被内联,没有性能损失.

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

传递变化的想法在 C++ 标准库中无处不在.它被称为策略模式.

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

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

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<<'	'<<e<<'
'; }, 1u);

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

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

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

这段代码并不完美,但你懂的.

This code is not perfect but you get the idea.

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

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 << '	' << 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;
}

同样,代码远非完美,但它为您提供了想法.

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

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

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