問題描述
我有一個名為 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語句?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!