LINUX.ORG.RU

max_element для всего контейнера

 ,


0

2

Не хочу указывать begin/end, а просто контейнер, но не пойму как реализовать враппер, так как max_element возвращает итератор.

const std::vector<int> numbers = { 1, 2, 3 };

// сейчас
std::max_element(numbers.begin(), numbers.end());

// хочу
std::max_element(numbers);
// Откуда взять Iter?
template <typename Iter, typename Container, typename Predicate>
Iter max_element(const Container &c, Predicate p)
{
    return std::max_element(std::begin(c), std::end(c), p);
}

PS: предикат обязателен. В примере я его опустил.

typename Container::iterator

anonymous ()
template<typename T>
typename T::const_iterator max_element(const T & c) {
	return std::max_element(std::begin(c), std::end(c));
}
anonymous ()
Ответ на: комментарий от anonymous

Спасибо добрый аноним. Что-то я к вечеру уже не соображаю.

RazrFalcon ★★★★★ ()
template <typename Container, typename Predicate>
auto max_element(const Container &c, Predicate p) -> typename Container::value_type
{
    return std::max_element(std::begin(c), std::end(c), p);
}
yoghurt ★★★★★ ()
Ответ на: комментарий от yoghurt

а, раз max_element возвращает итератор, то действительно typename Container::const_iterator

yoghurt ★★★★★ ()
Ответ на: комментарий от RazrFalcon
#include <iostream>
#include <algorithm>
#include <vector>

template <typename Container, typename Predicate>
auto max_element(const Container &c, Predicate p) -> decltype(std::cbegin(c))
{
    return std::max_element(std::cbegin(c), std::cend(c), p);
}

struct Data {
    int number;
    char letter;
};

int main(int argc, char *argv[])
{
    std::vector<Data> a = { Data { 1, 'a' }, Data { 2, 'b' }, Data { 3, 'c' }};
    // Подразумевается что контейнер не пуст
    char letter = max_element(a, [](const Data &l, const Data &r) { return l.number < r.number; })->letter;
    std::cout << letter << std::endl;
    return 0;
}
Deleted ()
Ответ на: комментарий от Deleted

А, и я совсем забыл что контейнеры из std имеют ассоциативные типы iterator(для begin/end) и const_iterator(для cbegin/cend). Т.е. Container::iterator и есть твой Iter для контейнеров std.

Deleted ()
#include <iostream>
#include <vector>
#include <algorithm>

template<typename T>
auto max_element(const T & c) -> decltype(std::begin(c)) {
	return std::max_element(std::begin(c), std::end(c));
}

int main() {
	std::vector<int> v { 1, 4, 2 };
	int a[] = { 5, 13, 7, 12 };
	std::cout << *max_element(v) << "\n";
	std::cout << *max_element(a) << "\n";
}
anonymous ()
Ответ на: комментарий от Deleted

опередил :)

Но вообще лучше юзать C++17 и забить на все эти танцы вокруг типов.

template<typename T>
auto max_element(const T & c) {
	return std::max_element(std::begin(c), std::end(c));
}
anonymous ()
Ответ на: комментарий от anonymous

Не обязательно ждать С++17, в C++14 это уже есть.

eao197 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.