Why can't I get value_type from iterator_traits?












13















I'm doing this:



const int arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
const auto foo = cbegin(arr);
const typename iterator_traits<decltype(foo)>::value_type bar = 1;


I would have expected bar to have the type int. But instead I'm getting an error:




error C2039: value_type: is not a member of std::iterator_traits<_Ty *const >




Is this a problem with the const do I need to strip that or something?










share|improve this question

























  • I generally use std::decay for this. Though, I'm reluctant to post this as an answer because I'm not entirely comfortable with why it seems to fix all of these problems. So it might not be the right solution. You would write const typename std::iterator_traits<std::decay_t<decltype(foo)>>::value_type bar = 1;.

    – François Andrieux
    Jan 9 at 15:29













  • @FrançoisAndrieux Yeah, I was hoping I could make this work for either a vector or an array... decay would still work there though... so maybe that's best?

    – Jonathan Mee
    Jan 9 at 15:32











  • @JonathanMee It does work for non-pointer iterator types as well. In my experience it fixes this kind of problem every time and magically works. Though again, the fact that it seems like magic to me leaves me nervous about recommending it.

    – François Andrieux
    Jan 9 at 15:33











  • @FantasticMrFox That change is intended to deal with volatile T*. It does not add a specialization for T* const.

    – xskxzr
    Jan 10 at 2:53
















13















I'm doing this:



const int arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
const auto foo = cbegin(arr);
const typename iterator_traits<decltype(foo)>::value_type bar = 1;


I would have expected bar to have the type int. But instead I'm getting an error:




error C2039: value_type: is not a member of std::iterator_traits<_Ty *const >




Is this a problem with the const do I need to strip that or something?










share|improve this question

























  • I generally use std::decay for this. Though, I'm reluctant to post this as an answer because I'm not entirely comfortable with why it seems to fix all of these problems. So it might not be the right solution. You would write const typename std::iterator_traits<std::decay_t<decltype(foo)>>::value_type bar = 1;.

    – François Andrieux
    Jan 9 at 15:29













  • @FrançoisAndrieux Yeah, I was hoping I could make this work for either a vector or an array... decay would still work there though... so maybe that's best?

    – Jonathan Mee
    Jan 9 at 15:32











  • @JonathanMee It does work for non-pointer iterator types as well. In my experience it fixes this kind of problem every time and magically works. Though again, the fact that it seems like magic to me leaves me nervous about recommending it.

    – François Andrieux
    Jan 9 at 15:33











  • @FantasticMrFox That change is intended to deal with volatile T*. It does not add a specialization for T* const.

    – xskxzr
    Jan 10 at 2:53














13












13








13








I'm doing this:



const int arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
const auto foo = cbegin(arr);
const typename iterator_traits<decltype(foo)>::value_type bar = 1;


I would have expected bar to have the type int. But instead I'm getting an error:




error C2039: value_type: is not a member of std::iterator_traits<_Ty *const >




Is this a problem with the const do I need to strip that or something?










share|improve this question
















I'm doing this:



const int arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
const auto foo = cbegin(arr);
const typename iterator_traits<decltype(foo)>::value_type bar = 1;


I would have expected bar to have the type int. But instead I'm getting an error:




error C2039: value_type: is not a member of std::iterator_traits<_Ty *const >




Is this a problem with the const do I need to strip that or something?







c++ types iterator typename iterator-traits






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 10 at 1:53









Peter Mortensen

13.6k1984111




13.6k1984111










asked Jan 9 at 15:23









Jonathan MeeJonathan Mee

21.6k1064167




21.6k1064167













  • I generally use std::decay for this. Though, I'm reluctant to post this as an answer because I'm not entirely comfortable with why it seems to fix all of these problems. So it might not be the right solution. You would write const typename std::iterator_traits<std::decay_t<decltype(foo)>>::value_type bar = 1;.

    – François Andrieux
    Jan 9 at 15:29













  • @FrançoisAndrieux Yeah, I was hoping I could make this work for either a vector or an array... decay would still work there though... so maybe that's best?

    – Jonathan Mee
    Jan 9 at 15:32











  • @JonathanMee It does work for non-pointer iterator types as well. In my experience it fixes this kind of problem every time and magically works. Though again, the fact that it seems like magic to me leaves me nervous about recommending it.

    – François Andrieux
    Jan 9 at 15:33











  • @FantasticMrFox That change is intended to deal with volatile T*. It does not add a specialization for T* const.

    – xskxzr
    Jan 10 at 2:53



















  • I generally use std::decay for this. Though, I'm reluctant to post this as an answer because I'm not entirely comfortable with why it seems to fix all of these problems. So it might not be the right solution. You would write const typename std::iterator_traits<std::decay_t<decltype(foo)>>::value_type bar = 1;.

    – François Andrieux
    Jan 9 at 15:29













  • @FrançoisAndrieux Yeah, I was hoping I could make this work for either a vector or an array... decay would still work there though... so maybe that's best?

    – Jonathan Mee
    Jan 9 at 15:32











  • @JonathanMee It does work for non-pointer iterator types as well. In my experience it fixes this kind of problem every time and magically works. Though again, the fact that it seems like magic to me leaves me nervous about recommending it.

    – François Andrieux
    Jan 9 at 15:33











  • @FantasticMrFox That change is intended to deal with volatile T*. It does not add a specialization for T* const.

    – xskxzr
    Jan 10 at 2:53

















I generally use std::decay for this. Though, I'm reluctant to post this as an answer because I'm not entirely comfortable with why it seems to fix all of these problems. So it might not be the right solution. You would write const typename std::iterator_traits<std::decay_t<decltype(foo)>>::value_type bar = 1;.

– François Andrieux
Jan 9 at 15:29







I generally use std::decay for this. Though, I'm reluctant to post this as an answer because I'm not entirely comfortable with why it seems to fix all of these problems. So it might not be the right solution. You would write const typename std::iterator_traits<std::decay_t<decltype(foo)>>::value_type bar = 1;.

– François Andrieux
Jan 9 at 15:29















@FrançoisAndrieux Yeah, I was hoping I could make this work for either a vector or an array... decay would still work there though... so maybe that's best?

– Jonathan Mee
Jan 9 at 15:32





@FrançoisAndrieux Yeah, I was hoping I could make this work for either a vector or an array... decay would still work there though... so maybe that's best?

– Jonathan Mee
Jan 9 at 15:32













@JonathanMee It does work for non-pointer iterator types as well. In my experience it fixes this kind of problem every time and magically works. Though again, the fact that it seems like magic to me leaves me nervous about recommending it.

– François Andrieux
Jan 9 at 15:33





@JonathanMee It does work for non-pointer iterator types as well. In my experience it fixes this kind of problem every time and magically works. Though again, the fact that it seems like magic to me leaves me nervous about recommending it.

– François Andrieux
Jan 9 at 15:33













@FantasticMrFox That change is intended to deal with volatile T*. It does not add a specialization for T* const.

– xskxzr
Jan 10 at 2:53





@FantasticMrFox That change is intended to deal with volatile T*. It does not add a specialization for T* const.

– xskxzr
Jan 10 at 2:53












3 Answers
3






active

oldest

votes


















8














Indeed the const is problematic, you do basically:



std::iterator_traits<const int* const>::value_type // incorrect due to the last const


You might fix it by changing it to



std::iterator_traits<const int*>::value_type // Correct


You might use std::decay or std::remove_cv for that:



const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type


(or drop const from foo if relevant).






share|improve this answer


























  • It's worth pointing out @FantasticMrFox's comment that the remove_cv_t happens automatically in C++20. So I'd say this is indeed the preferred solution.

    – Jonathan Mee
    Jan 9 at 18:59



















19














The issue here is with the line



const auto foo = cbegin(arr);


cbegin(arr) is going to return a int const * (pointer to const int) so applying const to that with const auto foo means foo is a int const * const (const pointer to const int)



std::iterator_traits is only specialized for a T* or T const* so giving it a T* const fails since there is no valid specialization.



You can fix this by removing the constness in the declaration of bar with



const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type


or you can change foo to



auto foo = std::cbegin(arr);


if you are okay with it not being const.






share|improve this answer





















  • 1





    It “fixes” the problem by weakening the type contract of foo. This is hardly a good solution: foo should be declared const. Don’t remove that!

    – Konrad Rudolph
    Jan 9 at 15:37






  • 1





    I agree with @KonradRudolph that it would be best to leave foo as const. I feel like it would be better to instead fix the template argument given to iterator_traits.

    – François Andrieux
    Jan 9 at 15:40






  • 1





    @KonradRudolph I've updated the answer but it really depends on what the OP wants to do with it. You can normally reassign const_iterators from containers so removing the const makes it behave the same.

    – NathanOliver
    Jan 9 at 15:47



















1














Declaring a const qualified iterator const auto foo = cbegin(arr); is questionable. What use do you have for an iterator on which you cannot apply operator++()? Also, the Iterator requirement requires the type int const *const to be Copy Assignable; as such, the variable foo does not satisfy the Iterator requirement. So strictly speaking, foo is not an Iterator.






share|improve this answer
























  • I mean next still works on it fine? It's the same argument against const char* const but in some cases this compiles into more optimized code than a const char*

    – Jonathan Mee
    Jan 9 at 18:25











  • @JonathanMee std::next requires an argument that satisfy LegacyInputIterator, which requires the type to be CopyAssignable through the LegacyIterator requirement. An Iterator type is intrinsically not const qualifiable.

    – Julien Villemure-Fréchette
    Jan 9 at 21:04













  • @JulienVillrmure-Fréchette I assume from your statement: "An Iterator type is intrinsically not const qualifiable." That you mean that the only way to modify a constant iterator would be to operate on a copy of it? And that generally the point of an iterator is modification?

    – Jonathan Mee
    Jan 9 at 21:47













  • Trivial example to a meaningful iterator constant: the end of a range. Though I also don't see a use-case for const cbegin...

    – stefan
    Jan 10 at 5:35











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',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
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%2f54113330%2fwhy-cant-i-get-value-type-from-iterator-traits%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









8














Indeed the const is problematic, you do basically:



std::iterator_traits<const int* const>::value_type // incorrect due to the last const


You might fix it by changing it to



std::iterator_traits<const int*>::value_type // Correct


You might use std::decay or std::remove_cv for that:



const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type


(or drop const from foo if relevant).






share|improve this answer


























  • It's worth pointing out @FantasticMrFox's comment that the remove_cv_t happens automatically in C++20. So I'd say this is indeed the preferred solution.

    – Jonathan Mee
    Jan 9 at 18:59
















8














Indeed the const is problematic, you do basically:



std::iterator_traits<const int* const>::value_type // incorrect due to the last const


You might fix it by changing it to



std::iterator_traits<const int*>::value_type // Correct


You might use std::decay or std::remove_cv for that:



const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type


(or drop const from foo if relevant).






share|improve this answer


























  • It's worth pointing out @FantasticMrFox's comment that the remove_cv_t happens automatically in C++20. So I'd say this is indeed the preferred solution.

    – Jonathan Mee
    Jan 9 at 18:59














8












8








8







Indeed the const is problematic, you do basically:



std::iterator_traits<const int* const>::value_type // incorrect due to the last const


You might fix it by changing it to



std::iterator_traits<const int*>::value_type // Correct


You might use std::decay or std::remove_cv for that:



const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type


(or drop const from foo if relevant).






share|improve this answer















Indeed the const is problematic, you do basically:



std::iterator_traits<const int* const>::value_type // incorrect due to the last const


You might fix it by changing it to



std::iterator_traits<const int*>::value_type // Correct


You might use std::decay or std::remove_cv for that:



const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type


(or drop const from foo if relevant).







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 9 at 15:41

























answered Jan 9 at 15:32









Jarod42Jarod42

116k12102182




116k12102182













  • It's worth pointing out @FantasticMrFox's comment that the remove_cv_t happens automatically in C++20. So I'd say this is indeed the preferred solution.

    – Jonathan Mee
    Jan 9 at 18:59



















  • It's worth pointing out @FantasticMrFox's comment that the remove_cv_t happens automatically in C++20. So I'd say this is indeed the preferred solution.

    – Jonathan Mee
    Jan 9 at 18:59

















It's worth pointing out @FantasticMrFox's comment that the remove_cv_t happens automatically in C++20. So I'd say this is indeed the preferred solution.

– Jonathan Mee
Jan 9 at 18:59





It's worth pointing out @FantasticMrFox's comment that the remove_cv_t happens automatically in C++20. So I'd say this is indeed the preferred solution.

– Jonathan Mee
Jan 9 at 18:59













19














The issue here is with the line



const auto foo = cbegin(arr);


cbegin(arr) is going to return a int const * (pointer to const int) so applying const to that with const auto foo means foo is a int const * const (const pointer to const int)



std::iterator_traits is only specialized for a T* or T const* so giving it a T* const fails since there is no valid specialization.



You can fix this by removing the constness in the declaration of bar with



const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type


or you can change foo to



auto foo = std::cbegin(arr);


if you are okay with it not being const.






share|improve this answer





















  • 1





    It “fixes” the problem by weakening the type contract of foo. This is hardly a good solution: foo should be declared const. Don’t remove that!

    – Konrad Rudolph
    Jan 9 at 15:37






  • 1





    I agree with @KonradRudolph that it would be best to leave foo as const. I feel like it would be better to instead fix the template argument given to iterator_traits.

    – François Andrieux
    Jan 9 at 15:40






  • 1





    @KonradRudolph I've updated the answer but it really depends on what the OP wants to do with it. You can normally reassign const_iterators from containers so removing the const makes it behave the same.

    – NathanOliver
    Jan 9 at 15:47
















19














The issue here is with the line



const auto foo = cbegin(arr);


cbegin(arr) is going to return a int const * (pointer to const int) so applying const to that with const auto foo means foo is a int const * const (const pointer to const int)



std::iterator_traits is only specialized for a T* or T const* so giving it a T* const fails since there is no valid specialization.



You can fix this by removing the constness in the declaration of bar with



const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type


or you can change foo to



auto foo = std::cbegin(arr);


if you are okay with it not being const.






share|improve this answer





















  • 1





    It “fixes” the problem by weakening the type contract of foo. This is hardly a good solution: foo should be declared const. Don’t remove that!

    – Konrad Rudolph
    Jan 9 at 15:37






  • 1





    I agree with @KonradRudolph that it would be best to leave foo as const. I feel like it would be better to instead fix the template argument given to iterator_traits.

    – François Andrieux
    Jan 9 at 15:40






  • 1





    @KonradRudolph I've updated the answer but it really depends on what the OP wants to do with it. You can normally reassign const_iterators from containers so removing the const makes it behave the same.

    – NathanOliver
    Jan 9 at 15:47














19












19








19







The issue here is with the line



const auto foo = cbegin(arr);


cbegin(arr) is going to return a int const * (pointer to const int) so applying const to that with const auto foo means foo is a int const * const (const pointer to const int)



std::iterator_traits is only specialized for a T* or T const* so giving it a T* const fails since there is no valid specialization.



You can fix this by removing the constness in the declaration of bar with



const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type


or you can change foo to



auto foo = std::cbegin(arr);


if you are okay with it not being const.






share|improve this answer















The issue here is with the line



const auto foo = cbegin(arr);


cbegin(arr) is going to return a int const * (pointer to const int) so applying const to that with const auto foo means foo is a int const * const (const pointer to const int)



std::iterator_traits is only specialized for a T* or T const* so giving it a T* const fails since there is no valid specialization.



You can fix this by removing the constness in the declaration of bar with



const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type


or you can change foo to



auto foo = std::cbegin(arr);


if you are okay with it not being const.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 9 at 15:42

























answered Jan 9 at 15:31









NathanOliverNathanOliver

91.2k15129193




91.2k15129193








  • 1





    It “fixes” the problem by weakening the type contract of foo. This is hardly a good solution: foo should be declared const. Don’t remove that!

    – Konrad Rudolph
    Jan 9 at 15:37






  • 1





    I agree with @KonradRudolph that it would be best to leave foo as const. I feel like it would be better to instead fix the template argument given to iterator_traits.

    – François Andrieux
    Jan 9 at 15:40






  • 1





    @KonradRudolph I've updated the answer but it really depends on what the OP wants to do with it. You can normally reassign const_iterators from containers so removing the const makes it behave the same.

    – NathanOliver
    Jan 9 at 15:47














  • 1





    It “fixes” the problem by weakening the type contract of foo. This is hardly a good solution: foo should be declared const. Don’t remove that!

    – Konrad Rudolph
    Jan 9 at 15:37






  • 1





    I agree with @KonradRudolph that it would be best to leave foo as const. I feel like it would be better to instead fix the template argument given to iterator_traits.

    – François Andrieux
    Jan 9 at 15:40






  • 1





    @KonradRudolph I've updated the answer but it really depends on what the OP wants to do with it. You can normally reassign const_iterators from containers so removing the const makes it behave the same.

    – NathanOliver
    Jan 9 at 15:47








1




1





It “fixes” the problem by weakening the type contract of foo. This is hardly a good solution: foo should be declared const. Don’t remove that!

– Konrad Rudolph
Jan 9 at 15:37





It “fixes” the problem by weakening the type contract of foo. This is hardly a good solution: foo should be declared const. Don’t remove that!

– Konrad Rudolph
Jan 9 at 15:37




1




1





I agree with @KonradRudolph that it would be best to leave foo as const. I feel like it would be better to instead fix the template argument given to iterator_traits.

– François Andrieux
Jan 9 at 15:40





I agree with @KonradRudolph that it would be best to leave foo as const. I feel like it would be better to instead fix the template argument given to iterator_traits.

– François Andrieux
Jan 9 at 15:40




1




1





@KonradRudolph I've updated the answer but it really depends on what the OP wants to do with it. You can normally reassign const_iterators from containers so removing the const makes it behave the same.

– NathanOliver
Jan 9 at 15:47





@KonradRudolph I've updated the answer but it really depends on what the OP wants to do with it. You can normally reassign const_iterators from containers so removing the const makes it behave the same.

– NathanOliver
Jan 9 at 15:47











1














Declaring a const qualified iterator const auto foo = cbegin(arr); is questionable. What use do you have for an iterator on which you cannot apply operator++()? Also, the Iterator requirement requires the type int const *const to be Copy Assignable; as such, the variable foo does not satisfy the Iterator requirement. So strictly speaking, foo is not an Iterator.






share|improve this answer
























  • I mean next still works on it fine? It's the same argument against const char* const but in some cases this compiles into more optimized code than a const char*

    – Jonathan Mee
    Jan 9 at 18:25











  • @JonathanMee std::next requires an argument that satisfy LegacyInputIterator, which requires the type to be CopyAssignable through the LegacyIterator requirement. An Iterator type is intrinsically not const qualifiable.

    – Julien Villemure-Fréchette
    Jan 9 at 21:04













  • @JulienVillrmure-Fréchette I assume from your statement: "An Iterator type is intrinsically not const qualifiable." That you mean that the only way to modify a constant iterator would be to operate on a copy of it? And that generally the point of an iterator is modification?

    – Jonathan Mee
    Jan 9 at 21:47













  • Trivial example to a meaningful iterator constant: the end of a range. Though I also don't see a use-case for const cbegin...

    – stefan
    Jan 10 at 5:35
















1














Declaring a const qualified iterator const auto foo = cbegin(arr); is questionable. What use do you have for an iterator on which you cannot apply operator++()? Also, the Iterator requirement requires the type int const *const to be Copy Assignable; as such, the variable foo does not satisfy the Iterator requirement. So strictly speaking, foo is not an Iterator.






share|improve this answer
























  • I mean next still works on it fine? It's the same argument against const char* const but in some cases this compiles into more optimized code than a const char*

    – Jonathan Mee
    Jan 9 at 18:25











  • @JonathanMee std::next requires an argument that satisfy LegacyInputIterator, which requires the type to be CopyAssignable through the LegacyIterator requirement. An Iterator type is intrinsically not const qualifiable.

    – Julien Villemure-Fréchette
    Jan 9 at 21:04













  • @JulienVillrmure-Fréchette I assume from your statement: "An Iterator type is intrinsically not const qualifiable." That you mean that the only way to modify a constant iterator would be to operate on a copy of it? And that generally the point of an iterator is modification?

    – Jonathan Mee
    Jan 9 at 21:47













  • Trivial example to a meaningful iterator constant: the end of a range. Though I also don't see a use-case for const cbegin...

    – stefan
    Jan 10 at 5:35














1












1








1







Declaring a const qualified iterator const auto foo = cbegin(arr); is questionable. What use do you have for an iterator on which you cannot apply operator++()? Also, the Iterator requirement requires the type int const *const to be Copy Assignable; as such, the variable foo does not satisfy the Iterator requirement. So strictly speaking, foo is not an Iterator.






share|improve this answer













Declaring a const qualified iterator const auto foo = cbegin(arr); is questionable. What use do you have for an iterator on which you cannot apply operator++()? Also, the Iterator requirement requires the type int const *const to be Copy Assignable; as such, the variable foo does not satisfy the Iterator requirement. So strictly speaking, foo is not an Iterator.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 9 at 16:57









Julien Villemure-FréchetteJulien Villemure-Fréchette

46517




46517













  • I mean next still works on it fine? It's the same argument against const char* const but in some cases this compiles into more optimized code than a const char*

    – Jonathan Mee
    Jan 9 at 18:25











  • @JonathanMee std::next requires an argument that satisfy LegacyInputIterator, which requires the type to be CopyAssignable through the LegacyIterator requirement. An Iterator type is intrinsically not const qualifiable.

    – Julien Villemure-Fréchette
    Jan 9 at 21:04













  • @JulienVillrmure-Fréchette I assume from your statement: "An Iterator type is intrinsically not const qualifiable." That you mean that the only way to modify a constant iterator would be to operate on a copy of it? And that generally the point of an iterator is modification?

    – Jonathan Mee
    Jan 9 at 21:47













  • Trivial example to a meaningful iterator constant: the end of a range. Though I also don't see a use-case for const cbegin...

    – stefan
    Jan 10 at 5:35



















  • I mean next still works on it fine? It's the same argument against const char* const but in some cases this compiles into more optimized code than a const char*

    – Jonathan Mee
    Jan 9 at 18:25











  • @JonathanMee std::next requires an argument that satisfy LegacyInputIterator, which requires the type to be CopyAssignable through the LegacyIterator requirement. An Iterator type is intrinsically not const qualifiable.

    – Julien Villemure-Fréchette
    Jan 9 at 21:04













  • @JulienVillrmure-Fréchette I assume from your statement: "An Iterator type is intrinsically not const qualifiable." That you mean that the only way to modify a constant iterator would be to operate on a copy of it? And that generally the point of an iterator is modification?

    – Jonathan Mee
    Jan 9 at 21:47













  • Trivial example to a meaningful iterator constant: the end of a range. Though I also don't see a use-case for const cbegin...

    – stefan
    Jan 10 at 5:35

















I mean next still works on it fine? It's the same argument against const char* const but in some cases this compiles into more optimized code than a const char*

– Jonathan Mee
Jan 9 at 18:25





I mean next still works on it fine? It's the same argument against const char* const but in some cases this compiles into more optimized code than a const char*

– Jonathan Mee
Jan 9 at 18:25













@JonathanMee std::next requires an argument that satisfy LegacyInputIterator, which requires the type to be CopyAssignable through the LegacyIterator requirement. An Iterator type is intrinsically not const qualifiable.

– Julien Villemure-Fréchette
Jan 9 at 21:04







@JonathanMee std::next requires an argument that satisfy LegacyInputIterator, which requires the type to be CopyAssignable through the LegacyIterator requirement. An Iterator type is intrinsically not const qualifiable.

– Julien Villemure-Fréchette
Jan 9 at 21:04















@JulienVillrmure-Fréchette I assume from your statement: "An Iterator type is intrinsically not const qualifiable." That you mean that the only way to modify a constant iterator would be to operate on a copy of it? And that generally the point of an iterator is modification?

– Jonathan Mee
Jan 9 at 21:47







@JulienVillrmure-Fréchette I assume from your statement: "An Iterator type is intrinsically not const qualifiable." That you mean that the only way to modify a constant iterator would be to operate on a copy of it? And that generally the point of an iterator is modification?

– Jonathan Mee
Jan 9 at 21:47















Trivial example to a meaningful iterator constant: the end of a range. Though I also don't see a use-case for const cbegin...

– stefan
Jan 10 at 5:35





Trivial example to a meaningful iterator constant: the end of a range. Though I also don't see a use-case for const cbegin...

– stefan
Jan 10 at 5:35


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54113330%2fwhy-cant-i-get-value-type-from-iterator-traits%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

A Topological Invariant for $pi_3(U(n))$