[解決済み] forループの中でif文を使わないようにするには?
質問
というクラスがあります。
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] << "\n";
}
}
パフォーマンスを気にしつつも、重複したコードを持たないようにしています。
関数の中で、私は
if (index)
のラウンドごとにチェックをしています。
for
-ループの各ラウンドで、たとえ結果が常に同じであっても、
の外側にチェックを置くことで、簡単にこれを回避することができました。
for
-ループの外側に配置することで簡単に回避できます。
しかし、重複するコードのロードを取得します。
void Drawer::writeVector(...)
{
if (index) {
for (...) {
cout << i << "\t" << vec[i] << "\n";
}
}
else {
for (...) {
cout << vec[i] << "\n";
}
}
}
つまり、これらは両方とも私にとって悪い解決策なのです。
私が考えているのは、2つのプライベート関数で、1つはインデックスを出力して、もう1つを呼び出すことです。
もう一方は値のみを出力します。
しかし、私のプログラムでは、それをどのように使うのかがわかりません。
if
をチェックし、どちらを呼び出すかを確認する必要があります...
問題によると、ポリモーフィズムは正しい解決策のように思えます。 しかし、私はここでそれをどのように使用すべきかを見ることができません。 この種の問題を解決するために望ましい方法は何でしょうか?
これは本当のプログラムではありません。 この種の問題をどのように解決するのが望ましいかを知りたいだけです。
どのように解決するのですか?
ループの本体をファンクタとして渡す。 コンパイル時にインライン化され、性能上のペナルティはありません。
変化するものを渡すという考え方は、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'};
// 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'; });
}
このコードは完璧ではありませんが、アイデアを得ることができます。
古い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 << '\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;
}
繰り返しになりますが、このコードは完璧ではありませんが、アイデアを与えてくれます。
関連
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み] JavaScriptのオブジェクトをループスルーまたは列挙するにはどうすればよいですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] 配列の反復処理に "for...in "を使用するのは、なぜ良くないのでしょうか?
-
[解決済み] Javaでenumを繰り返し処理するためのforループ
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み] 見たこともないC++のforループ
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】識別子 "string "は未定義?
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】C++コンパイルタイムエラー:数値定数の前に期待される識別子
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複