この記事は以下の続きです
char[][]
に対するalgorithmが欲しい
C++はその標準ライブラリの一部であるSTLにて、ジェネリックプログラミングで各種処理を抽象化した関数群(algorithm)が用意されている。sort
とかcount
とか、for eachまで。
そして、C++(そのベースとなったC言語由来だが)で文字列は文字の配列(char[]
)として表現する都合上、『文字列の配列』は文字の二次元配列(char[][]
)として表現する事になる(std::string[]
については此処では触れない)。
……じゃあ、『文字列の配列』用に特殊化したalgorithmが欲しくなるよね?
char[][]
に対するstd::find()
を実装する
……という訳で、char[][]
用のstd::find()
を実装してみた。同じようにして、wchar_t[][]
用や、他のalgorithmも実装出来る筈。
#include <algorithm>
#include <functional>
#include <cstddef>
#include <cstring>
#define NS aslib
// #define NS std
// ↑ユーザー定義型用の完全特殊化以外をstd名前空間に記述するのは本当は×
namespace {
template<typename Itr>
Itr find_detail_for_char2darray(Itr begin, Itr end, const char *target) {
return std::find_if(begin, end,
std::not1(std::bind2nd(std::ptr_fun(std::strcmp), target))
);
}
}
namespace NS {
template<std::size_t N>
const char (*find(const char (*begin)[N], const char (*end)[N], const char *target))[N] {
return ::find_detail_for_char2darray(begin, end, target);
}
#if NS==std
// std下に置く場合は、以下の特殊化の定義も必要となる
template<std::size_t N>
char (*find(char (*begin)[N], char (*end)[N], const char *target))[N] {
return find_detail_for_char2darray(begin, end, target);
}
template<std::size_t N>
const char (*find(const char (*begin)[N], const char (*end)[N], char *target))[N] {
return find_detail_for_char2darray(begin, end, target);
}
template<std::size_t N>
char (*find(char (*begin)[N], char (*end)[N], char *target))[N] {
return find_detail_for_char2darray(begin, end, target);
}
#endif
}
ソースはこちら。おまけで確認用のmain()
も記述している。Ideone.comにもUPしているので、そちらの方が手軽かも知れない。
ソース中でも言及しているが、本来、std
名前空間下には、ユーザー定義型用に完全特殊化したもの以外は追加してはいけない事になっている(らしい)。
char[][]
と同じ名前空間(上記の場合はaslib
)下に、std::find()
を呼び出すだけの汎用版を用意し、同じインタフェイスで使えるようにするのがスマートかも知れない。
ラベル:C++