Pull to refresh

Comments 15

Про min и max. Пишем
#define NOMINMAX
и эти макросы не определены.
Да, именно эти макросы будут не определены (другие макросы вашим методом не обойти).
+ нельзя так писать в заголовочных файлах библиотеки, которая будет использоваться третьими лицами — это может поломать их код.
Да, я понимаю это. Но вообще такие проблемы правильнее решать на уровне «Coding Style», и серьезно наказывать за отклонения от него.
Уже позно, MS много лет назад определила кучу макросов в WinAPI.
+ нельзя так писать в заголовочных файлах библиотеки, которая будет использоваться третьими лицами — это может поломать их код.

Отмечу, что при использовании cl для обхода этого момента можно использовать:
#pragma push_macro("min")
#undef min
// a lot of code
#pragma pop_macro("min")
для gcc и подобных компиляторов есть аналоги (наизусть не помню, там обычно таких проблем не возникает).

Но вариант со скобками мне нравиться гораздо больше чем эти непереносимые решения.
В заглавии статьи указан С++, в нет нет макросов min и max, равно как и макросов __min и __max. Это вольности microsoft. Другими словами, такие проблемы являются проблемами стиля программирования, а не проблемами совместимости. Собственно это я имел в виду.
Есть кстати еще пример о пользе скобочек при использовании макросов:
#define SOME_MACRO(x)	(x)

template<typename T1, typename T2>
T2 some_func(T1 x)
{
	return x;
}

int main()
{
	SOME_MACRO(1 == (some_func<int,int>(1)));

	return 0;
}

Без скобочек вокруг вызова функции даже не компилируется.
Так и описано, что это касается не только MIN и MAX, но и других макросов, а в данном случае описана просто техника.
Извините, но разве это трюки/советы? Ладно, с макросами — трюк, но vector::reserve, swap — это ведь и не трюки, и не советы. И статья на статью не тянет.
Извините ещё раз.
Хочу поблагодарить автора за книгу по Boost. Книг по этой библиотеке вообще крайне мало (по бусту в целом всего 3 штуки, включая сабжевую).
Читал сабжевую книгу, в целом, неплохая. Но написана очень сложным для прочтения английским, полным русизмов. Но на безрыбье выбирать не приходится.
По поводу swap: по-моему проще определить move конструктор и оператор присваивания, вместо того, чтобы придумывать свой swap.
По поводу:
В C++11 было решено, что std::vector и ряд других контейнеров могут использовать move-конструкторы и move-assignment операторы для элементов только если move-конструкторы и move-assignment операторы этих элементов не кидают исключений (ну или если элементы не могут копироваться).

А с чем это связано? Не очень понятно, чем в случае кидающего исключения move-конструктора лучше кидающий исключения copy-конструктор.
В случае конструктора копирования, если N-й элемент при копировании выбросит исключение, то предыдущие N-1 элементов будут существовать одновременно в двух векторах, по этому, в новом векторе можно будет вызвать для них деструкторы, корректно освободить память, а исходный вектор не изменится.
Если перемещающий оператор/конструктор сгенерирует исключение, то первые N-1 элемент будут в новом векторе, а N+1 и последующие в старом и безопасно откатиться из этого состояния не получится — исходный вектор окажется в несогласованном состоянии.
Начнем с достаточно тривиального совета: если вы знаете количество элементов, которые будут вставлены в вектор, то перед вставкой необходимо вызвать reserve


В таком виде совет может быть вреден. Например, в STL Microsoft (VC11), если добавлять элементы порциями, то вызов reserve перед каждой порцией значительно снижает производительность по сравнению с дефолтным экспоненциальным расширением. То есть правильнее сказать: "… если знаете максимальное кол-во эл-тов..."
Sign up to leave a comment.

Articles