9

Out of curiosity, what's the rationale to use a template parameter for std::advance()'s distance type, but use the iterator's difference_type for the distance in std::next() and std::prev()?

Why not use the same approach (either one)?

Follow up:

Presence of default n = 1 does not seem to prevent next to be templated by Distance as was suggested in the answer below. This compiles:

#include <iterator>
#include <set>

template<typename InputIt,
    typename Distance = typename std::iterator_traits<InputIt>::difference_type>
InputIt my_next(InputIt it, Distance n = 1)
{
    std::advance(it, n);
    return it;
}

int main()
{
    std::set<int> s;
    my_next(s.begin());
    my_next(s.begin(), 10ul);

    return 0;
}
user2052436
  • 4,321
  • 1
  • 25
  • 46
  • Not a duplicate, but closely related to https://stackoverflow.com/questions/15017065/whats-the-difference-between-stdadvance-and-stdnext – dan04 Sep 01 '21 at 23:33
  • 1
    I would say "history", `std::next` is from C++11, and has stronger type (and changing `std::advance` would certainly break ABI and/or other retro-compatibility concerns). – Jarod42 Sep 02 '21 at 10:32

1 Answers1

1

It is needed to be able to compile both std::next(it, n) and std::next(it) with default 1:

template<typename InputIt , typename Distance>
InputIt 
next(InputIt it, Distance n = 1)
{
    std::advance(it, n);
    return it;
}

void foo(int *p)
{
    next(p, 1);         // ok
    next<int*, int>(p); // ok
    next(p);  // error: no matching function for call to 'next(int*&)'
}

There is a discussion of possible approaches to this overload resolution issue in gcc bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40497

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
dewaffled
  • 2,850
  • 2
  • 17
  • 30
  • I don't follow. `std::next` doesn't even have a second template parameter. – cigien Sep 02 '21 at 01:24
  • 1
    @cigien I think this is demonstrating why exactly we cannot have a second template parameter (it prevents the use of a default parameter) – ph3rin Sep 02 '21 at 01:27
  • 2
    @Meowmere I'm not sure I understand. The second template parameter could have a default as well, say `typename Distance = int`, and then the `next(p)` call in this answer would compile just fine. – cigien Sep 02 '21 at 01:30
  • BTW, it only "answers" one possibility, `std::advance` might use `difference_type` (and possible implementation of en.cppreference.com uses it). – Jarod42 Sep 02 '21 at 10:26