質問
のようなものを書きたいと思っています
char f(char);
vector<char> bar;
vector<char> foo = map(f, bar);
transform
関数は似ているように見えますが、結果のコレクションのサイズを自己拡張しません。
解決
使用できます std::back_inserter
の <iterator>
, 、前にサイズを提供する方が効率的です。例えば:
string str = "hello world!", result;
transform(str.begin(), str.end(), back_inserter(result), ::toupper);
// result == "HELLO WORLD!"
他のヒント
この質問は、C ++ 11規格が施行される前に尋ねられました...今日私たちは持っています std::transform()
機能的なプログラミング「マップ」に相当する(ugい)として。使用方法は次のとおりです。
auto f(char) -> char; // or if you like: char f(char)
vector<char> bar;
vector<char> foo;
// ... initialize bar somehow ...
std::transform(bar.begin(), bar.end(), std::back_inserter(foo), f);
この作業を行うには、次の観察が必要です。
- 割り当てを効率的にするために
map
関数は必要です いいえ 仕事をする。代わりに、それはその引数を一時的なオブジェクトに保存する必要があります(あなたの場合、それはclass map::result<char(*)(char), vector<char> >
) - これ
map::result
一時的なものが必要ですtemplate <typename T> operator T
変換。 - いつ
map::result
に割り当てられますstd::vector<char>
, 、この変換は唯一の実行可能です。 - 変換演算子で
class map::result<char(*)(char), vector<char> >::operator vector<char>
入力と戻りのタイプ、およびマッピング機能があります。この時点で、入力を効果的に変換できます。
<edit>
コード
template<typename CONT, typename FUNC>
class mapresult {
CONT const& in;
FUNC f;
public:
template<typename RESULT> RESULT to() const
{
RESULT out;
for (auto const& e : in) { out.push_back(f(e)); }
return out;
}
template<typename RESULT> operator RESULT() const
{
return this->to<RESULT>();
}
mapresult(CONT const& in, FUNC f) : in(in), f(std::move(f)) { }
};
template<typename CONT, typename FUNC>
auto map(CONT const& in, FUNC f) -> mapresult<CONT, FUNC>
{
return mapresult<CONT, FUNC>(in, f);
}
このように使用:
using namespace std;
char foo(char c) { return c | ('A' ^ 'a'); }
std::string in = "Test";
int main(int argc, char* argv[])
{
string out = map(in, &foo);
cout << out << endl;
char replace = 'e';
cout << map(in, [replace](char c){return c == replace ? '?' : c; }).to<string>();
}
所属していません StackOverflow