Вы можете использовать
std::remove_reference_t<decltype(std::declval<Container>()[0])>
Все, что находится внутри decltype
, не оценено, поэтому тот факт, что доступ к элементу 0 гипотетического пустого контейнера является UB, не имеет значения.Это просто извлекает необходимую информацию о типе из контейнера operator[]
.Вам нужен remove_reference
, потому что operator[]
, вероятно, возвращает ссылку на lvalue.
Однако это не будет работать для контейнера, такого как std::list<T>
.Вместо этого вы можете использовать:
typename std::iterator_traits<typename Container::iterator>::value_type
Если вы не можете предположить, что существует Container::iterator
, вы можете заменить typename Container::iterator
на decltype(std::declval<Container>().begin())
.