einpoklum
einpoklum

Reputation: 131475

What's the idiomatic way to get a backwards inserter with a fallback to any inserter?

I want to insert elements into a STL container (whose type is a template parameter). If the container allows for back_insertion, I want to use that, otherwise just any inserter.

I would like to avoid having to implement my own trait just for this, I'm pretty sure there must be someway I could say "instantiate a back_inserter if possible, and an inserter otherwise".

How do I do that?

Upvotes: 1

Views: 57

Answers (1)

Barry
Barry

Reputation: 302748

You could use a trailing return type with overload resolution to do something like:

namespace impl
{
   // preferred overload: if we can push_back a Container::value_type
   template <class Container>
   auto generic_inserter(Container& c, int)
       -> decltype(void(c.push_back(std::declval<typename Container::value_type>())),
                   std::back_inserter(c))
    {
        return std::back_inserter(c);
    }

    // fallback if we can't
    template <Container>
    auto generic_inserter(Container& c, ...)
    {
        return std::inserter(c, c.end());
    }
}

template <class Container>
auto generic_inserter(Container& c)
{
    return impl::generic_inserter(c, 0);
}

With C++11, simply replace the auto return types with decltype(body-of-function).

Upvotes: 3

Related Questions