Can we increase an iterator multiple positions without the 'advance' function?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite
1












I know we can use advance() function to increment the iterator. We also use iterator++ to increase the iterator by one position. Why we cannot use it+=2?



int main()

list<int> l11, 2, 3, 5, 6;
list<int> l22, 6, 8;
auto it = l1.begin();
advance(it, 2); //works
it++; //works
// it+=2; //not work
l2.splice(l2.begin(), l1, it);

for(int a: l2) cout<<a<<" ";
cout<<endl;

return 0;



You can run the above code here.










share|improve this question



















  • 6




    List has a bidirectional iterator, not a random access iterator. advance uses compile time machinery to optimize advance operation for different kinds of iterators.
    – William Lee
    9 hours ago











  • So your question is: "why wasn't operator+=() specified as syntactic sugar around std::advance()?" or is it really "why can't I use operator+=() here?"
    – moooeeeep
    8 hours ago















up vote
7
down vote

favorite
1












I know we can use advance() function to increment the iterator. We also use iterator++ to increase the iterator by one position. Why we cannot use it+=2?



int main()

list<int> l11, 2, 3, 5, 6;
list<int> l22, 6, 8;
auto it = l1.begin();
advance(it, 2); //works
it++; //works
// it+=2; //not work
l2.splice(l2.begin(), l1, it);

for(int a: l2) cout<<a<<" ";
cout<<endl;

return 0;



You can run the above code here.










share|improve this question



















  • 6




    List has a bidirectional iterator, not a random access iterator. advance uses compile time machinery to optimize advance operation for different kinds of iterators.
    – William Lee
    9 hours ago











  • So your question is: "why wasn't operator+=() specified as syntactic sugar around std::advance()?" or is it really "why can't I use operator+=() here?"
    – moooeeeep
    8 hours ago













up vote
7
down vote

favorite
1









up vote
7
down vote

favorite
1






1





I know we can use advance() function to increment the iterator. We also use iterator++ to increase the iterator by one position. Why we cannot use it+=2?



int main()

list<int> l11, 2, 3, 5, 6;
list<int> l22, 6, 8;
auto it = l1.begin();
advance(it, 2); //works
it++; //works
// it+=2; //not work
l2.splice(l2.begin(), l1, it);

for(int a: l2) cout<<a<<" ";
cout<<endl;

return 0;



You can run the above code here.










share|improve this question















I know we can use advance() function to increment the iterator. We also use iterator++ to increase the iterator by one position. Why we cannot use it+=2?



int main()

list<int> l11, 2, 3, 5, 6;
list<int> l22, 6, 8;
auto it = l1.begin();
advance(it, 2); //works
it++; //works
// it+=2; //not work
l2.splice(l2.begin(), l1, it);

for(int a: l2) cout<<a<<" ";
cout<<endl;

return 0;



You can run the above code here.







c++ c++11 iterator listiterator






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 13 mins ago









Justin

12.7k95094




12.7k95094










asked 9 hours ago









Lusha Li

542




542







  • 6




    List has a bidirectional iterator, not a random access iterator. advance uses compile time machinery to optimize advance operation for different kinds of iterators.
    – William Lee
    9 hours ago











  • So your question is: "why wasn't operator+=() specified as syntactic sugar around std::advance()?" or is it really "why can't I use operator+=() here?"
    – moooeeeep
    8 hours ago













  • 6




    List has a bidirectional iterator, not a random access iterator. advance uses compile time machinery to optimize advance operation for different kinds of iterators.
    – William Lee
    9 hours ago











  • So your question is: "why wasn't operator+=() specified as syntactic sugar around std::advance()?" or is it really "why can't I use operator+=() here?"
    – moooeeeep
    8 hours ago








6




6




List has a bidirectional iterator, not a random access iterator. advance uses compile time machinery to optimize advance operation for different kinds of iterators.
– William Lee
9 hours ago





List has a bidirectional iterator, not a random access iterator. advance uses compile time machinery to optimize advance operation for different kinds of iterators.
– William Lee
9 hours ago













So your question is: "why wasn't operator+=() specified as syntactic sugar around std::advance()?" or is it really "why can't I use operator+=() here?"
– moooeeeep
8 hours ago





So your question is: "why wasn't operator+=() specified as syntactic sugar around std::advance()?" or is it really "why can't I use operator+=() here?"
– moooeeeep
8 hours ago













2 Answers
2






active

oldest

votes

















up vote
24
down vote













operator += is only supported by RandomAccessIterator; note that it's supposed to have constant complexity.



The iterator of std::list is BidirectionalIterator, which doesn't support operator +=. (The iterator of std::vector and std::array is RandomAccessIterator.)



Note that both of them could be used with std::advance, when used for RandomAccessIterator complexity is constant; when used for other InputIterators (including BidirectionalIterator) complexity is linear. That means using std::advance is a good idea because it's more general and could take advantage of the benefit of RandomAccessIterator automatically.






share|improve this answer


















  • 2




    Whether std::advance is a good idea depends on the complexity guarantee you wish for your algorithm. Using += ensures that should somebody accidentally call your algorithm with a non-RandomAccessIterator, they will get a compile-time error instead of a painfully slow algorithm. For example, if std::sort used std::advance, you could call it on std::list...
    – Matthieu M.
    2 hours ago

















up vote
13
down vote













You cannot use += 2 with this iterator because in general case incrementing std::list<> iterator by an arbitrary value is a relatively inefficient operation. += is not defined for your iterator type specifically to prevent you from carelessly/unknowingly using this inefficient operation in your code. Instead, if you really want to do that you are supposed to use std::advance, which is a "red flag" function that is intended to highlight the fact that you are likely doing something inefficient. std::advance is mostly intended for code sketching or for unlikely-to-get-executed fallback code. You are not supposed to use std::advance in real production code. If you suddenly find yourself relying on std::advance, it means that you probably need to redesign your data structures. Basically, std::advance is like a cast - you are not supposed to use it unless you have a very very very good reason to.



Alternatively, you can use std::next



it = std::next(it, 2);


This function is much easier to use than std::advance. By default this function is designed to advance the iterator by 1 step forward, but you can specify the second parameter to move it farther. Again, when the value of second parameter is potentially large, it should be considered a "red flag" function. A constant value of 2 is definitely within acceptable bounds.






share|improve this answer


















  • 1




    The reason that += is associated with a constant time operation, is possibly because pointers are normally the first iterator type that one is introduced to and naturally supports pointer arithmetic from its c legacy - just neat to understand that this interface design was more or less forced onto c++ by existing culture.
    – WorldSEnder
    6 hours ago






  • 2




    @WorldSEnder -- += is associated with constant time operation because that's the way the STL (Standard Template Library) was designed: iterator operations are constant-time. Period. Things like std::advance and std::next are conveniences that were added by revisionists who didn't understand the elegance of the original formulation. <g> But seriously: those are conveniences, and they're named functions and not operators to help make it clear that they can be expensive.
    – Pete Becker
    2 hours ago










Your Answer





StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53002491%2fcan-we-increase-an-iterator-multiple-positions-without-the-advance-function%23new-answer', 'question_page');

);

Post as a guest






























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
24
down vote













operator += is only supported by RandomAccessIterator; note that it's supposed to have constant complexity.



The iterator of std::list is BidirectionalIterator, which doesn't support operator +=. (The iterator of std::vector and std::array is RandomAccessIterator.)



Note that both of them could be used with std::advance, when used for RandomAccessIterator complexity is constant; when used for other InputIterators (including BidirectionalIterator) complexity is linear. That means using std::advance is a good idea because it's more general and could take advantage of the benefit of RandomAccessIterator automatically.






share|improve this answer


















  • 2




    Whether std::advance is a good idea depends on the complexity guarantee you wish for your algorithm. Using += ensures that should somebody accidentally call your algorithm with a non-RandomAccessIterator, they will get a compile-time error instead of a painfully slow algorithm. For example, if std::sort used std::advance, you could call it on std::list...
    – Matthieu M.
    2 hours ago














up vote
24
down vote













operator += is only supported by RandomAccessIterator; note that it's supposed to have constant complexity.



The iterator of std::list is BidirectionalIterator, which doesn't support operator +=. (The iterator of std::vector and std::array is RandomAccessIterator.)



Note that both of them could be used with std::advance, when used for RandomAccessIterator complexity is constant; when used for other InputIterators (including BidirectionalIterator) complexity is linear. That means using std::advance is a good idea because it's more general and could take advantage of the benefit of RandomAccessIterator automatically.






share|improve this answer


















  • 2




    Whether std::advance is a good idea depends on the complexity guarantee you wish for your algorithm. Using += ensures that should somebody accidentally call your algorithm with a non-RandomAccessIterator, they will get a compile-time error instead of a painfully slow algorithm. For example, if std::sort used std::advance, you could call it on std::list...
    – Matthieu M.
    2 hours ago












up vote
24
down vote










up vote
24
down vote









operator += is only supported by RandomAccessIterator; note that it's supposed to have constant complexity.



The iterator of std::list is BidirectionalIterator, which doesn't support operator +=. (The iterator of std::vector and std::array is RandomAccessIterator.)



Note that both of them could be used with std::advance, when used for RandomAccessIterator complexity is constant; when used for other InputIterators (including BidirectionalIterator) complexity is linear. That means using std::advance is a good idea because it's more general and could take advantage of the benefit of RandomAccessIterator automatically.






share|improve this answer














operator += is only supported by RandomAccessIterator; note that it's supposed to have constant complexity.



The iterator of std::list is BidirectionalIterator, which doesn't support operator +=. (The iterator of std::vector and std::array is RandomAccessIterator.)



Note that both of them could be used with std::advance, when used for RandomAccessIterator complexity is constant; when used for other InputIterators (including BidirectionalIterator) complexity is linear. That means using std::advance is a good idea because it's more general and could take advantage of the benefit of RandomAccessIterator automatically.







share|improve this answer














share|improve this answer



share|improve this answer








edited 9 hours ago

























answered 9 hours ago









songyuanyao

86.9k10167228




86.9k10167228







  • 2




    Whether std::advance is a good idea depends on the complexity guarantee you wish for your algorithm. Using += ensures that should somebody accidentally call your algorithm with a non-RandomAccessIterator, they will get a compile-time error instead of a painfully slow algorithm. For example, if std::sort used std::advance, you could call it on std::list...
    – Matthieu M.
    2 hours ago












  • 2




    Whether std::advance is a good idea depends on the complexity guarantee you wish for your algorithm. Using += ensures that should somebody accidentally call your algorithm with a non-RandomAccessIterator, they will get a compile-time error instead of a painfully slow algorithm. For example, if std::sort used std::advance, you could call it on std::list...
    – Matthieu M.
    2 hours ago







2




2




Whether std::advance is a good idea depends on the complexity guarantee you wish for your algorithm. Using += ensures that should somebody accidentally call your algorithm with a non-RandomAccessIterator, they will get a compile-time error instead of a painfully slow algorithm. For example, if std::sort used std::advance, you could call it on std::list...
– Matthieu M.
2 hours ago




Whether std::advance is a good idea depends on the complexity guarantee you wish for your algorithm. Using += ensures that should somebody accidentally call your algorithm with a non-RandomAccessIterator, they will get a compile-time error instead of a painfully slow algorithm. For example, if std::sort used std::advance, you could call it on std::list...
– Matthieu M.
2 hours ago












up vote
13
down vote













You cannot use += 2 with this iterator because in general case incrementing std::list<> iterator by an arbitrary value is a relatively inefficient operation. += is not defined for your iterator type specifically to prevent you from carelessly/unknowingly using this inefficient operation in your code. Instead, if you really want to do that you are supposed to use std::advance, which is a "red flag" function that is intended to highlight the fact that you are likely doing something inefficient. std::advance is mostly intended for code sketching or for unlikely-to-get-executed fallback code. You are not supposed to use std::advance in real production code. If you suddenly find yourself relying on std::advance, it means that you probably need to redesign your data structures. Basically, std::advance is like a cast - you are not supposed to use it unless you have a very very very good reason to.



Alternatively, you can use std::next



it = std::next(it, 2);


This function is much easier to use than std::advance. By default this function is designed to advance the iterator by 1 step forward, but you can specify the second parameter to move it farther. Again, when the value of second parameter is potentially large, it should be considered a "red flag" function. A constant value of 2 is definitely within acceptable bounds.






share|improve this answer


















  • 1




    The reason that += is associated with a constant time operation, is possibly because pointers are normally the first iterator type that one is introduced to and naturally supports pointer arithmetic from its c legacy - just neat to understand that this interface design was more or less forced onto c++ by existing culture.
    – WorldSEnder
    6 hours ago






  • 2




    @WorldSEnder -- += is associated with constant time operation because that's the way the STL (Standard Template Library) was designed: iterator operations are constant-time. Period. Things like std::advance and std::next are conveniences that were added by revisionists who didn't understand the elegance of the original formulation. <g> But seriously: those are conveniences, and they're named functions and not operators to help make it clear that they can be expensive.
    – Pete Becker
    2 hours ago














up vote
13
down vote













You cannot use += 2 with this iterator because in general case incrementing std::list<> iterator by an arbitrary value is a relatively inefficient operation. += is not defined for your iterator type specifically to prevent you from carelessly/unknowingly using this inefficient operation in your code. Instead, if you really want to do that you are supposed to use std::advance, which is a "red flag" function that is intended to highlight the fact that you are likely doing something inefficient. std::advance is mostly intended for code sketching or for unlikely-to-get-executed fallback code. You are not supposed to use std::advance in real production code. If you suddenly find yourself relying on std::advance, it means that you probably need to redesign your data structures. Basically, std::advance is like a cast - you are not supposed to use it unless you have a very very very good reason to.



Alternatively, you can use std::next



it = std::next(it, 2);


This function is much easier to use than std::advance. By default this function is designed to advance the iterator by 1 step forward, but you can specify the second parameter to move it farther. Again, when the value of second parameter is potentially large, it should be considered a "red flag" function. A constant value of 2 is definitely within acceptable bounds.






share|improve this answer


















  • 1




    The reason that += is associated with a constant time operation, is possibly because pointers are normally the first iterator type that one is introduced to and naturally supports pointer arithmetic from its c legacy - just neat to understand that this interface design was more or less forced onto c++ by existing culture.
    – WorldSEnder
    6 hours ago






  • 2




    @WorldSEnder -- += is associated with constant time operation because that's the way the STL (Standard Template Library) was designed: iterator operations are constant-time. Period. Things like std::advance and std::next are conveniences that were added by revisionists who didn't understand the elegance of the original formulation. <g> But seriously: those are conveniences, and they're named functions and not operators to help make it clear that they can be expensive.
    – Pete Becker
    2 hours ago












up vote
13
down vote










up vote
13
down vote









You cannot use += 2 with this iterator because in general case incrementing std::list<> iterator by an arbitrary value is a relatively inefficient operation. += is not defined for your iterator type specifically to prevent you from carelessly/unknowingly using this inefficient operation in your code. Instead, if you really want to do that you are supposed to use std::advance, which is a "red flag" function that is intended to highlight the fact that you are likely doing something inefficient. std::advance is mostly intended for code sketching or for unlikely-to-get-executed fallback code. You are not supposed to use std::advance in real production code. If you suddenly find yourself relying on std::advance, it means that you probably need to redesign your data structures. Basically, std::advance is like a cast - you are not supposed to use it unless you have a very very very good reason to.



Alternatively, you can use std::next



it = std::next(it, 2);


This function is much easier to use than std::advance. By default this function is designed to advance the iterator by 1 step forward, but you can specify the second parameter to move it farther. Again, when the value of second parameter is potentially large, it should be considered a "red flag" function. A constant value of 2 is definitely within acceptable bounds.






share|improve this answer














You cannot use += 2 with this iterator because in general case incrementing std::list<> iterator by an arbitrary value is a relatively inefficient operation. += is not defined for your iterator type specifically to prevent you from carelessly/unknowingly using this inefficient operation in your code. Instead, if you really want to do that you are supposed to use std::advance, which is a "red flag" function that is intended to highlight the fact that you are likely doing something inefficient. std::advance is mostly intended for code sketching or for unlikely-to-get-executed fallback code. You are not supposed to use std::advance in real production code. If you suddenly find yourself relying on std::advance, it means that you probably need to redesign your data structures. Basically, std::advance is like a cast - you are not supposed to use it unless you have a very very very good reason to.



Alternatively, you can use std::next



it = std::next(it, 2);


This function is much easier to use than std::advance. By default this function is designed to advance the iterator by 1 step forward, but you can specify the second parameter to move it farther. Again, when the value of second parameter is potentially large, it should be considered a "red flag" function. A constant value of 2 is definitely within acceptable bounds.







share|improve this answer














share|improve this answer



share|improve this answer








edited 9 hours ago

























answered 9 hours ago









AnT

254k31404652




254k31404652







  • 1




    The reason that += is associated with a constant time operation, is possibly because pointers are normally the first iterator type that one is introduced to and naturally supports pointer arithmetic from its c legacy - just neat to understand that this interface design was more or less forced onto c++ by existing culture.
    – WorldSEnder
    6 hours ago






  • 2




    @WorldSEnder -- += is associated with constant time operation because that's the way the STL (Standard Template Library) was designed: iterator operations are constant-time. Period. Things like std::advance and std::next are conveniences that were added by revisionists who didn't understand the elegance of the original formulation. <g> But seriously: those are conveniences, and they're named functions and not operators to help make it clear that they can be expensive.
    – Pete Becker
    2 hours ago












  • 1




    The reason that += is associated with a constant time operation, is possibly because pointers are normally the first iterator type that one is introduced to and naturally supports pointer arithmetic from its c legacy - just neat to understand that this interface design was more or less forced onto c++ by existing culture.
    – WorldSEnder
    6 hours ago






  • 2




    @WorldSEnder -- += is associated with constant time operation because that's the way the STL (Standard Template Library) was designed: iterator operations are constant-time. Period. Things like std::advance and std::next are conveniences that were added by revisionists who didn't understand the elegance of the original formulation. <g> But seriously: those are conveniences, and they're named functions and not operators to help make it clear that they can be expensive.
    – Pete Becker
    2 hours ago







1




1




The reason that += is associated with a constant time operation, is possibly because pointers are normally the first iterator type that one is introduced to and naturally supports pointer arithmetic from its c legacy - just neat to understand that this interface design was more or less forced onto c++ by existing culture.
– WorldSEnder
6 hours ago




The reason that += is associated with a constant time operation, is possibly because pointers are normally the first iterator type that one is introduced to and naturally supports pointer arithmetic from its c legacy - just neat to understand that this interface design was more or less forced onto c++ by existing culture.
– WorldSEnder
6 hours ago




2




2




@WorldSEnder -- += is associated with constant time operation because that's the way the STL (Standard Template Library) was designed: iterator operations are constant-time. Period. Things like std::advance and std::next are conveniences that were added by revisionists who didn't understand the elegance of the original formulation. <g> But seriously: those are conveniences, and they're named functions and not operators to help make it clear that they can be expensive.
– Pete Becker
2 hours ago




@WorldSEnder -- += is associated with constant time operation because that's the way the STL (Standard Template Library) was designed: iterator operations are constant-time. Period. Things like std::advance and std::next are conveniences that were added by revisionists who didn't understand the elegance of the original formulation. <g> But seriously: those are conveniences, and they're named functions and not operators to help make it clear that they can be expensive.
– Pete Becker
2 hours ago

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53002491%2fcan-we-increase-an-iterator-multiple-positions-without-the-advance-function%23new-answer', 'question_page');

);

Post as a guest













































































Comments

Popular posts from this blog

Long meetings (6-7 hours a day): Being “babysat” by supervisor

Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

Confectionery