Template Type Limitations

Suppose I want to implement a Maphigher order generic function in C ++. Mapshould take the container and the conversion function and return a container of the same type, but possibly with different types of elements.

Take vectorfor example:

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);
    }
}

which I want to use as follows:

vector<int> v(10);
std::iota(v.begin(), v.end(), 0);
auto x = Map(v, [](int x) -> int {return x * 2;});

This does not work in VC ++ 2012, which gives me the following error:

error C2783: 'std::vector<OutT> Map(std::vector<_Ty>,Tr)' : could not deduce template argument for 'OutT'   

It seems to me that the compiler has all the necessary information, because I explicitly determined the return type in lambda. Is there any way around this?

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
}
+4
1

- :

template <typename InT, typename Tr>
auto Map(std::vector<InT> cont, Tr tr) -> std::vector<decltype(tr(cont[0]))>
{
    std::vector<decltype(tr(cont[0]))> out(cont.size());
    auto oit = out.begin();
    for (auto it = cont.cbegin(); it != cont.cend(); ++it, ++oit)
    {
        *oit = tr(*it);
    }
    return out;
}

.

[] :

template <template<typename, typename...> class Container, typename InT, typename Tr, typename... Args>
auto Map(const Container<InT, Args...>& cont, Tr tr) -> Container<decltype(tr(cont[0])), Args...>
{
    Container<decltype(tr(cont[0])), Args...> out(cont.size());
    auto oit = out.begin();
    for (auto it = cont.cbegin(); it != cont.cend(); ++it, ++oit)
    {
        *oit = tr(*it);
    }
    return out;
}

typename..., std::vector

+4

All Articles