Wrapper for a standard STL-container
I question the value of this template class.  We hide many important members of std::unordered_map (including crbegin(), empty(), reserve(), at(), try_emplace()) for no good reason.  The additional functions that are provided have no business being members: they are perfectly implementable as free functions without privileged access.

Considering the members in turn:


insert(): only instantiable if T is convertible to the map's value_type.  Unnecessarily copies the argument.
operator(): unnecessary, given that we have operator[].
operator[]: unnecessarily copies its argument.
find(), size() begin(), end(): required only because the map is private.
exists(): should be a free function.  If this is generic, why is the parameter called userId?
remove() - why not just use the erase() that accepts a key?  Or do we have to build with pre-C++11 library?




When I've wanted to provide something like the exists() here, I've made it a standalone template function that can work with many kinds of container:



/*
 * contains()
 * A convenience overload that searches from beginning to end of a container.
 *
 * If an iterator is supplied, it will be written with the found position or
 * container.end() as appropriate.
 */
template&lt;typename T, typename U&gt;
inline bool contains(const T&amp; container, const U&amp; value)
{
    using std::begin;
    using std::end;
    return find(begin(container), end(container), value) != end;
}

template&lt;typename T, typename U, typename Iter&gt;
    /* Iter should be a T::iterator or T::const_iterator */
inline bool contains(T&amp; container, const U&amp; value, Iter&amp; it)
{
    using std::begin;
    using std::end;
    return (it = find(begin(container), end(container), value)) != end;
}




/*
 * Overloads for pointer-to-const values within containers of pointer-to-mutable.
 */
template&lt;typename T, typename U&gt;
inline bool contains(const T&amp; container, const U* value)
{
    using std::begin;
    using std::end;
    return find(begin(container), end(container), value) != end;
}

template&lt;typename T, typename U, typename Iter&gt;
inline bool contains(const T&amp; container, const U* value, Iter&amp; it)
{
    using std::begin;
    using std::end;
    return (it = find(begin(container), end(container), value)) != end;
}




/*
 * Overloads for maps (by key)
 */
template&lt;typename T&gt;
inline bool contains(const T&amp; container, const typename T::key_type&amp; key)
{
    return container.find(key) != container.end();
}

template&lt;typename T, typename Iter&gt;
inline bool contains(T&amp; container, const typename T::key_type&amp; key, Iter&amp; it)
{
    return (it = container.find(key)) != container.end();
}

template&lt;typename T&gt;
inline bool contains(const T&amp; container, const typename T::key_type&amp; key,
                     typename T::mapped_type&amp; result)
{
    typename T::const_iterator it;
    return contains(container, key, it) &amp;&amp; (result = it-&gt;second, true);
}