LINUX.ORG.RU

Стандартный алгоритмы в С++


0

0

Почему есть два стандартых алгоритма: один с аргументом-функтором второй без оного (напиример mismatch) Почему бы не сделать из этих двух один с аргументом по умолчанию? Старауструп на 590 странице своего фалианта чего-то говорит про разницу в случае использования указателей на функции, но я чего-то не въезжаю...

GCC говорит, что стандарт 98 года не позволяет дефолтные значения параметров шаблона в шаблонах функций. Ну да ладно, врубаем C++0x. Вот такой вариант вроде бы работает:

#include <iterator>

template<typename InputIterator, typename Pred = std::less<typename std::iterator_traits<InputIterator>::value_type>>
static bool is_sorted(InputIterator first, InputIterator last, Pred pred = Pred())
{
	if (first == last)
		return true;

	for (InputIterator prev = first++; first != last; prev = first++) {
		if (pred(*first, *prev))
			return false;
	}

	return true;
}
Но выглядит страшновато :) Может, в стандарте так не сделано, потому что два прототипа вместо одного не накладывают каких-либо ограничений для пользователя, но зато хоть выглядят проще.

const86 ★★★★★
()

По крайней мере это не эффективно. В каждом вызове будет инстанциироваться этот самый умолчальный функтор.

k_andy ★★★
()
Ответ на: комментарий от k_andy

> В каждом вызове будет инстанциироваться этот самый умолчальный функтор.

Со включенной оптимизацией он лихо инлайнится, так что ничего от него не остаётся и получается то же самое, что и вовсе без предиката.

const86 ★★★★★
()
Ответ на: комментарий от const86

Со включенной оптимизацией он лихо инлайнится, так что ничего от него не остаётся и получается то же самое, что и вовсе без предиката.

Только увеличивает время компиляции.

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

> Только увеличивает время компиляции.

Да. Но вряд ли это ответ на исходный вопрос.

const86 ★★★★★
()
Ответ на: комментарий от const86

Ну Я вообщето говоря имел ввиду не дефолтный параметр щаблона, а дефолтное значение соответствующего аргумента:

 template<typename InputIterator, typename Pred> 
static bool is_sorted(InputIterator first, InputIterator last, Pred pred = std::less<typename std::iterator_traits<InputIterator>::value_type>( )
Тпк-то почему плохо? И при чкм тут указатели на функции?

mskmsk1985
() автор топика
Ответ на: комментарий от const86

> Со включенной оптимизацией он лихо инлайнится, так что ничего от него не остаётся и получается то же самое, что и вовсе без предиката.

В лучшем случае будет инлайнится до константы. Исчезнуть предикат не может.

k_andy ★★★
()
Ответ на: комментарий от mskmsk1985

> Тпк-то почему плохо?

А у меня так не хочет работать, но я не могу сообразить, почему :)

И при чкм тут указатели на функции?

Вот уж не знаю. В мой вариант можно и указатели на функции передавать. Или в книжке что-то другое? У меня нет её, не могу посмотреть.

const86 ★★★★★
()
Ответ на: комментарий от mskmsk1985

>default template arguments may not be used in function templates

то есть чтобы получить сигнатуру для вызова с двумя аргументами, обязательно нужно сначала вывести тип дефолтного значения pred, чтобы из него вывести тип Pred
но std::less<typename std::iterator_traits<InputIterator>::value_type> зависит от шаблонного параметра, и чтобы вывести его тип, нужно получить сигнатуру функции.

компилятор обычно выводит сначала сигнатуру, а потом уже все что от нее зависит, а не поочереди: вывел тип InputIterator, вывел аргументы зависящие от InputIterator, вывел тип Pred. поэтому такой пример не обязан работать

а так как объявление std::sort зафиксированно в стандарте, то выбрано то, которое будет работать в любом компиляторе

как-то так

gavv
()
Ответ на: комментарий от gavv

компилятор обычно выводит сначала сигнатуру, а потом уже все что от нее зависит, а не поочереди: вывел тип InputIterator, вывел аргументы зависящие от InputIterator, вывел тип Pred. поэтому такой пример не обязан работать

А вот, например, такое в стандарте написано:

template <class T, class Allocator = allocator<T> >
class vector;
Или между функциями и классами конкретно по этому вопросу какие-то существенные различия есть? Даже если и есть, можно запихнуть такой vector в параметр, например, шаблона функции make_pair.

const86 ★★★★★
()
Ответ на: комментарий от const86

так здесь дефолтное значение типа, а не аргумента
в функциях запрещены дефолтные значения типов
а дефолтные значения аргуметов выводятся _перед выводом сигнатуры, и не могут от нее зависеть (в gcc, в стандарте хз)

gavv
()
Ответ на: комментарий от const86

>запихнуть такой vector в параметр, например, шаблона функции make_pair
не понял, что имеется в виду

gavv
()
Ответ на: комментарий от gavv

>в gcc, в стандарте хз
да, и такое поведение является допустимым

gavv
()
Ответ на: комментарий от gavv

> так здесь дефолтное значение типа, а не аргумента

Понятно, это мы о разном говорили :)

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