Map
C++ で一般的な高階関数を実装したいとします。Map
コンテナと変換関数を取り、同じタイプのコンテナを返す必要がありますが、アイテムのタイプが異なる可能性があります。
vector
たとえば、次のように考えてみましょう。
template <typename InT, typename OutT, typename Tr>
vector<OutT> Map(vector<InT> cont, Tr tr)
{
OutCont out(cont.size());
auto oit = out.begin();
for (auto it = cont.cbegin(); it != cont.cend(); ++it, ++ot)
{
*oit = tr(*it);
}
}
私はこのように使いたい:
vector<int> v(10);
std::iota(v.begin(), v.end(), 0);
auto x = Map(v, [](int x) -> int {return x * 2;});
これは VC++ 2012 では失敗し、次のエラーが表示されます。
error C2783: 'std::vector<OutT> Map(std::vector<_Ty>,Tr)' : could not deduce template argument for 'OutT'
ラムダで戻り値の型を明示的に定義したため、コンパイラには必要な情報がすべて含まれているように思えます。これを回避する方法はありますか?
上記の例では、 を使用していvector
ます。入力と出力の型が同じになるように、ジェネリック型を使用する方法はありますか? たとえば、入力コンテナがvector<string>
と変換関数として定義されている場合tr(string a) -> int
、私の目標は、コンパイラが出力タイプを であると判断するようにすることvector<int>
です。私が達成したいことの擬似コードは次のとおりです。
template <typename Cont<InT>, typename Cont<OutT>, typename Tr<InT, OutT>>
Cont<OutT> Map(Cont<InT> cont, Tr<InT, OutT> tr)
{
// Implementation
}