https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81944
Bug ID: 81944 Summary: constexpr std::distance Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: alexbaroni68 at gmail dot com Target Milestone: --- When using the constexpr overload of std::distance it complains that a not constexpr function is called, follows code to reproduce and error message: #include <iostream> #include <algorithm> #include <iterator> #include <stdexcept> #include <array> #include <string> #include <cassert> template<typename It> constexpr auto max (It first, It last) { auto count = std::distance(first, last); if (count == 0) throw std::domain_error{"max is undefined on empty range"}; if (count == 1) return *first; auto mid = first + (last - first) / 2; return std::max(max(first, mid), max(mid, last)); } int main() { constexpr std::array<int, 4> vs{1,6,8,3}; constexpr auto max_of_vs = max(std::cbegin(vs), std::cend(vs)); assert(max_of_vs == 8); std::cout << max_of_vs << std::endl; std::array<int, 5> xs{1,9,8,3,6}; auto max_of_xs = max(std::begin(xs), std::end(xs)); assert(max_of_xs == 9); std::cout << max_of_xs << std::endl; //std::array<int, 0> zs{}; //auto max_of_zs = max(std::begin(zs), std::end(zs)); // throws at runtime //assert(max_of_zs == 0); } main.cpp: In function 'int main()': main.cpp:23:33: in constexpr expansion of 'max<const int*>(std::cbegin<std::array<int, 4> >(vs), std::cend<std::array<int, 4> >(vs))' main.cpp:12:29: error: 'constexpr typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = const int*; typename std::iterator_traits<_Iterator>::difference_type = long int]' called in a constant expression auto count = std::distance(first, last); ~~~~~~~~~~~~~^~~~~~~~~~~~~ In file included from /usr/local/include/c++/7.2.0/bits/stl_algobase.h:66:0, from /usr/local/include/c++/7.2.0/bits/char_traits.h:39, from /usr/local/include/c++/7.2.0/ios:40, from /usr/local/include/c++/7.2.0/ostream:38, from /usr/local/include/c++/7.2.0/iostream:39, from main.cpp:1: /usr/local/include/c++/7.2.0/bits/stl_iterator_base_funcs.h:138:5: note: 'constexpr typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = const int*; typename std::iterator_traits<_Iterator>::difference_type = long int]' is not usable as a constexpr function because: distance(_InputIterator __first, _InputIterator __last) ^~~~~~~~ /usr/local/include/c++/7.2.0/bits/stl_iterator_base_funcs.h:142:33: error: call to non-constexpr function 'typename std::iterator_traits<_Iterator>::iterator_category std::__iterator_category(const _Iter&) [with _Iter = const int*; typename std::iterator_traits<_Iterator>::iterator_category = std::random_access_iterator_tag]' std::__iterator_category(__first)); ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~