Consider two overloads of the std::directory_iterator constructor,
explicit directory_iterator(const std::filesystem::path& p); // (1a)
directory_iterator(const std::filesystem::path& p,
std::error_code& ec); // (1b)
(1a), which throws, and (1b), which takes a std::error_code& parameter.
Now, suppose directory_iterator were to have an overload that took an
allocator parameter. It doesn't, but suppose that it did. Consistent with
Standard Library design guidelines, such as they are, which overload
would you expect to see
directory_iterator(const std::filesystem::path& p,
const Allocator& alloc = Allocator()); // (2a)
directory_iterator(const std::filesystem::path& p,
const Allocator& alloc,
std::error_code& ec); // (2b)
or
directory_iterator(const std::filesystem::path& p,
const Allocator& alloc = Allocator()); // (3a)
directory_iterator(const std::filesystem::path& p,
std::error_code& ec,
const Allocator& alloc = Allocator()); // (3b)
or
directory_iterator(std::allocator_arg_t,
const Allocator& alloc,
const std::filesystem::path& p); // (4a)
directory_iterator(std::allocator_arg_t,
const Allocator& alloc,
const std::filesystem::path& p,
std::error_code& ec); // (4b)
(2b) doesn't follow any of the user-allocator construction conventions,
https://en.cppreference.com/w/cpp/memory/uses_allocator#Uses-allocator_construction. (3b) looks disjointed.
Thanks,
Daniel