2016-04-28 12 views
1

Я хочу вставить элементы в контейнер STL (тип которого является параметром шаблона). Если контейнер разрешает back_insertion, я хочу использовать его, иначе как любой вставщик.Что такое идиоматический способ получить обратный вставку с резервным доступом к любому вставнику?

Я хотел бы избежать необходимости реализовать свою собственную черту только для этого, я уверен, что должно быть что-то, что я могу сказать: «Создайте экземпляр back_inserter, если это возможно, и вставку в противном случае».

Как это сделать?

ответ

3

Вы можете использовать косую тип возвращаемого значения с разрешением перегрузки, чтобы сделать что-то вроде:

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

С C++ 11, просто замените auto возвращаемые типы с decltype(body-of-function).

+0

Итак, ничего в самой библиотеке? Хм. ОК. – einpoklum

+0

Какова цель 'void (...)' around 'c.push_back'? – Holt

+0

@Holt Чтобы избежать перегруженного 'operator,' – Barry