C ++ 17 будет (вероятно) ослабить определение диапазона для цикла, позволяющий end()
чтобы возвратить отдельный тип (например, страж):
struct MyRange {
struct Sentinel {};
int* begin();
Sentinel end();
};
bool operator!=(int*, MyRange::Sentinel);
На данный момент единственными компиляторами, поддерживающими это, являются gcc 6.1 и clang 4.0+ (пример) (пример сообщения об ошибке). Если я пишу тип диапазона, где сторож был бы более эффективным для конечного типа, как я могу определить, поддерживает ли компилятор ослабленный диапазон? Я не вижу никакого обсуждения этого в P0184R0 (ссылка выше); будет ли предоставлен макрос тестирования функции?
Дальнейшие вопросы:
end()
функция-член? Мне нужно, например, сделать моего стража неявно конвертируемым в мой тип итератора?sentinel()
)? Могут ли эффективно использовать алгоритмы до C ++ 17 [begin(), sentinel())
или это не стоит дополнительного кода?в P0096R3, Вы можете проверить, __cpp_range_based_for
больше или равно 201603. Конечно, Visual Studio не поддерживает любой из макроса функционального теста, так что вам придется проверять его версии отдельно. Они поставили поддержку для него в VS2015 Update 3, но наряду с большинством других поддержки C ++ 17, вы должны использовать /std:c++latest
переключатель.
Причина, по которой дозорные эффективны, редко связана с внутренним состоянием стража.
Так что один из подходов — дать Sentinel
достаточно внутреннего состояния, чтобы сгенерировать версию самого итератора.
Даже в C ++ 14 с единообразным началом for(:)
циклы и алгоритмы, которые настаивают на идентичных типах итераторов начала / конца, рукописные алгоритмы или циклы могут использовать ваш дозорный и повысить эффективность.
Библиотека как Boost.Config Обычно это лучшая ставка, если вы хотите получить максимальный охват, но набор функций обнаружения C ++ 17 не был опубликован на эту дату (что я могу найти).
Насколько я могу судить, СФИНАЕ не существует способа обнаружить существование for(:)
циклы, которые принимают разные типы начала / конца итератора. (Я мог представить что-то constexpr
нет, кроме того, что что-то взломано, но это не в моем умении
Обнаружение, если <algorithms>
принять итераторы конца дозорного, вероятно, можно с помощью SFINAE. Но я не уверен, даже если C ++ 17 имеет дозорный <algorithms>
или даже собирается; range-v3 должен справиться с переделкой этого.