0

I'm not sure if it is specified in the standard that advance/dereference of standard container iterator are noexcept. GCC and MSVC consistently make them noexcept for all standard containers. But clang make them noexcept for std::vector/std::basic_string and noexcept(false) for std::list/std::set/std::map/std::unordered_set/std::unordered_map.

Example code could be found below or on godbolt.

#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <vector>
#include <list>
#include <string>
#include <ranges>

template<typename Iterator>
concept nothrow_advancable = noexcept(++std::declval<Iterator&>());

template<typename Iterator>
concept nothrow_dereferencable = noexcept(*std::declval<Iterator&>());

static_assert(nothrow_advancable<std::ranges::iterator_t<std::vector<int>&>>);
static_assert(nothrow_advancable<std::ranges::iterator_t<std::basic_string<char>&>>);
static_assert(nothrow_advancable<std::ranges::iterator_t<std::list<int>&>>); // not noexcept with clang
static_assert(nothrow_advancable<std::ranges::iterator_t<std::set<int>&>>); // not noexcept with clang
static_assert(nothrow_advancable<std::ranges::iterator_t<std::map<int, int>&>>); // not noexcept with clang
static_assert(nothrow_advancable<std::ranges::iterator_t<std::unordered_set<int>&>>); // not noexcept with clang
static_assert(nothrow_advancable<std::ranges::iterator_t<std::unordered_map<int, int>&>>); // not noexcept with clang

static_assert(nothrow_dereferencable<std::ranges::iterator_t<std::vector<int>&>>);
static_assert(nothrow_dereferencable<std::ranges::iterator_t<std::basic_string<char>&>>);
static_assert(nothrow_dereferencable<std::ranges::iterator_t<std::list<int>&>>); // not noexcept with clang
static_assert(nothrow_dereferencable<std::ranges::iterator_t<std::set<int>&>>); // not noexcept with clang
static_assert(nothrow_dereferencable<std::ranges::iterator_t<std::map<int, int>&>>); // not noexcept with clang
static_assert(nothrow_dereferencable<std::ranges::iterator_t<std::unordered_set<int>&>>); // not noexcept with clang
static_assert(nothrow_dereferencable<std::ranges::iterator_t<std::unordered_map<int, int>&>>); // not noexcept with clang
7
  • Extra noexcept can be added from vendors, (contrary to constexpr, even if gcc did it). Commented Jan 8 at 14:57
  • From en.cppreference.com/w/cpp/container/list, list::iterator is a BidirectionalIterator, and no mention of noexcept. Commented Jan 8 at 15:00
  • I think being a BidirectionalIterator is not related to evaluating noexcept(++it) and noexcept(*it). Commented Jan 8 at 15:52
  • 1
    Those containers would use sentinel and not past-to-end iterator; that might change something... Commented Jan 8 at 15:57
  • 1
    If you feel clang should "follow the same logic" your best option is to create an issue on clang's bug tracker. If it's straightforward, they'd probably appreciate a pull request. Commented Jan 8 at 16:08

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.