Why does std::cbegin() not call .cbegin() on the container?Why does std::cbegin return the same type as std::beginWhat does the explicit keyword mean?Why can templates only be implemented in the header file?Why is “using namespace std;” considered bad practice?Why are elementwise additions much faster in separate loops than in a combined loop?Why does changing 0.1f to 0 slow down performance by 10x?Why is reading lines from stdin much slower in C++ than Python?Why is processing a sorted array faster than processing an unsorted array?Why should I use a pointer rather than the object itself?Should I return gsl::span<const T> instead of const std::vector<T>&How to properly deduce a dereferenced type of the iterator returned from std::set::begin()?

PDF page & word count, recursive searching of directory tree, output to excel

Proof of Isoperimetric Inequality using Curve Shortening Flow

Is it okay to roll multiple attacks that all have advantage in one cluster?

What is the minimum time required for final wash in film development?

Why different specifications for telescopes and binoculars?

Are there any sports for which the world's best player is female?

Is a request to book a business flight ticket for a graduate student an unreasonable one?

When an electron changes its spin, or any other intrinsic property, is it still the same electron?

Why does wrapping Aluminium foil around my food help it keep warm, aluminium be good conductor should have no effect?

What minifigure is this?

Is there a nice way to implement a conditional type with default fail case?

Misrepresented my work history

Could you brine steak?

Postgres Trigram acting strange for specific characters

Is there any reason why MCU changed the Snap to Blip

Stacked light circle effect in Photoshop?

How quality assurance engineers test calculations?

When did "&" stop being taught alongside the alphabet?

Is system.schedule(...) @AuraEnabled?

What is this little owl-like bird?

How effective would wooden scale armor be in a medieval setting?

Data Encryption by Application vs Data Encryption in Database

What in New Testament invalidates God’s commandments from the Old Testament?

What does 오지다 mean?



Why does std::cbegin() not call .cbegin() on the container?


Why does std::cbegin return the same type as std::beginWhat does the explicit keyword mean?Why can templates only be implemented in the header file?Why is “using namespace std;” considered bad practice?Why are elementwise additions much faster in separate loops than in a combined loop?Why does changing 0.1f to 0 slow down performance by 10x?Why is reading lines from stdin much slower in C++ than Python?Why is processing a sorted array faster than processing an unsorted array?Why should I use a pointer rather than the object itself?Should I return gsl::span<const T> instead of const std::vector<T>&How to properly deduce a dereferenced type of the iterator returned from std::set::begin()?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








16















The following code fails the static assertion:



#include <gsl/span>
#include <iterator>
#include <type_traits>

int main()

int theArr[] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ;
gsl::span<int> theSpan theArr, std::size(theArr) ;

using std::cbegin;
auto it1 = cbegin(theSpan);
auto it2 = theSpan.cbegin();
static_assert(std::is_same_v<decltype(it1), decltype(it2)>);



This fails because std::cbegin() calls the .begin() method on a const ref of the container. For standard-defined containers, this returns a const_iterator, which is the same type that .cbegin() returns. However, gsl::span is a bit unique because it models a sort of "borrow type". A const gsl::span behaves like a const pointer; the span itself is const, but what it points-to is not const. Hence, the .begin() method on a const gsl::span still returns a non-const iterator, whereas explicitly calling .cbegin() returns a const iterator.



I'm curious as to why std::cbegin() was not defined as invoking .cbegin() on the container (which all standard containers seem to implement) to account for cases such as this.



This is somewhat related to: Why does std::cbegin return the same type as std::begin










share|improve this question

















  • 1





    for reference : "auto cbegin( const C& c ) returns exactly std::begin(c)"

    – bolov
    Jun 30 at 23:53


















16















The following code fails the static assertion:



#include <gsl/span>
#include <iterator>
#include <type_traits>

int main()

int theArr[] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ;
gsl::span<int> theSpan theArr, std::size(theArr) ;

using std::cbegin;
auto it1 = cbegin(theSpan);
auto it2 = theSpan.cbegin();
static_assert(std::is_same_v<decltype(it1), decltype(it2)>);



This fails because std::cbegin() calls the .begin() method on a const ref of the container. For standard-defined containers, this returns a const_iterator, which is the same type that .cbegin() returns. However, gsl::span is a bit unique because it models a sort of "borrow type". A const gsl::span behaves like a const pointer; the span itself is const, but what it points-to is not const. Hence, the .begin() method on a const gsl::span still returns a non-const iterator, whereas explicitly calling .cbegin() returns a const iterator.



I'm curious as to why std::cbegin() was not defined as invoking .cbegin() on the container (which all standard containers seem to implement) to account for cases such as this.



This is somewhat related to: Why does std::cbegin return the same type as std::begin










share|improve this question

















  • 1





    for reference : "auto cbegin( const C& c ) returns exactly std::begin(c)"

    – bolov
    Jun 30 at 23:53














16












16








16








The following code fails the static assertion:



#include <gsl/span>
#include <iterator>
#include <type_traits>

int main()

int theArr[] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ;
gsl::span<int> theSpan theArr, std::size(theArr) ;

using std::cbegin;
auto it1 = cbegin(theSpan);
auto it2 = theSpan.cbegin();
static_assert(std::is_same_v<decltype(it1), decltype(it2)>);



This fails because std::cbegin() calls the .begin() method on a const ref of the container. For standard-defined containers, this returns a const_iterator, which is the same type that .cbegin() returns. However, gsl::span is a bit unique because it models a sort of "borrow type". A const gsl::span behaves like a const pointer; the span itself is const, but what it points-to is not const. Hence, the .begin() method on a const gsl::span still returns a non-const iterator, whereas explicitly calling .cbegin() returns a const iterator.



I'm curious as to why std::cbegin() was not defined as invoking .cbegin() on the container (which all standard containers seem to implement) to account for cases such as this.



This is somewhat related to: Why does std::cbegin return the same type as std::begin










share|improve this question














The following code fails the static assertion:



#include <gsl/span>
#include <iterator>
#include <type_traits>

int main()

int theArr[] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ;
gsl::span<int> theSpan theArr, std::size(theArr) ;

using std::cbegin;
auto it1 = cbegin(theSpan);
auto it2 = theSpan.cbegin();
static_assert(std::is_same_v<decltype(it1), decltype(it2)>);



This fails because std::cbegin() calls the .begin() method on a const ref of the container. For standard-defined containers, this returns a const_iterator, which is the same type that .cbegin() returns. However, gsl::span is a bit unique because it models a sort of "borrow type". A const gsl::span behaves like a const pointer; the span itself is const, but what it points-to is not const. Hence, the .begin() method on a const gsl::span still returns a non-const iterator, whereas explicitly calling .cbegin() returns a const iterator.



I'm curious as to why std::cbegin() was not defined as invoking .cbegin() on the container (which all standard containers seem to implement) to account for cases such as this.



This is somewhat related to: Why does std::cbegin return the same type as std::begin







c++






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jun 30 at 23:20









TripShockTripShock

2,0313 gold badges21 silver badges30 bronze badges




2,0313 gold badges21 silver badges30 bronze badges







  • 1





    for reference : "auto cbegin( const C& c ) returns exactly std::begin(c)"

    – bolov
    Jun 30 at 23:53













  • 1





    for reference : "auto cbegin( const C& c ) returns exactly std::begin(c)"

    – bolov
    Jun 30 at 23:53








1




1





for reference : "auto cbegin( const C& c ) returns exactly std::begin(c)"

– bolov
Jun 30 at 23:53






for reference : "auto cbegin( const C& c ) returns exactly std::begin(c)"

– bolov
Jun 30 at 23:53













2 Answers
2






active

oldest

votes


















12















this fails because std::cbegin() calls the .begin()




To be more precise, std::cbegin calls std::begin, which in the generic overload calls c.begin.



For what it's worth, it should be possible to fix gsl::span to return const iterator upon std::cbegin if the designers of gsl specify that there is a specialisation for the generic overload of std::cbegin for gsl::span that uses c.cbegin instead of std::begin, if that is the desired behaviour. I don't know their reasoning for not specifying such specialisation.



As for reasoning for why std::cbegin uses std::begin, I do not know for fact either, but it does have the advantage of being able to support containers that have a c.begin member, but not a c.cbegin member, which can be seen as a less strict requirement, as it can be satisfied by custom containers written prior to C++11, when there was no convention of providing a c.cbegin member function.






share|improve this answer

























  • "std::span does propagate constness" - does it? It doesn't look like that to me from how the member functions are declared. Looking at P0122, it seems that not propagating constness was a design goal.

    – bogdan
    Jul 1 at 10:58











  • @bogdan you're right. I misread the member function declarations.

    – eerorika
    Jul 1 at 11:10


















9














First, note that, per [tab:container.req]:




Expression: a.cbegin()



Return type: const_­iterator



Operational semantics: const_­cast<​X const&​>(a)​.begin();



Complexity: constant




Therefore, gsl::span is not a container at all. cbegin and cend are designed to work with containers. There are some exceptions (arrays, initializer_list) that require special care, but apparently the standard library cannot mention something like gsl::span.



Second, it is LWG 2128 that introduced global cbegin and cend. Let's see what the relevant part says:




Implement std::cbegin/cend() by calling std::begin/end(). This has
numerous advantages:



  • It automatically works with arrays, which is the whole point of these non-member functions.


  • It works with C++98/03-era user containers, written before cbegin/cend() members were invented.


  • It works with initializer_list, which is extremely minimal and lacks cbegin/cend() members.


  • [container.requirements.general]
    guarantees that this is equivalent to calling cbegin/cend() members.




Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.






share|improve this answer

























    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%2f56828691%2fwhy-does-stdcbegin-not-call-cbegin-on-the-container%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    12















    this fails because std::cbegin() calls the .begin()




    To be more precise, std::cbegin calls std::begin, which in the generic overload calls c.begin.



    For what it's worth, it should be possible to fix gsl::span to return const iterator upon std::cbegin if the designers of gsl specify that there is a specialisation for the generic overload of std::cbegin for gsl::span that uses c.cbegin instead of std::begin, if that is the desired behaviour. I don't know their reasoning for not specifying such specialisation.



    As for reasoning for why std::cbegin uses std::begin, I do not know for fact either, but it does have the advantage of being able to support containers that have a c.begin member, but not a c.cbegin member, which can be seen as a less strict requirement, as it can be satisfied by custom containers written prior to C++11, when there was no convention of providing a c.cbegin member function.






    share|improve this answer

























    • "std::span does propagate constness" - does it? It doesn't look like that to me from how the member functions are declared. Looking at P0122, it seems that not propagating constness was a design goal.

      – bogdan
      Jul 1 at 10:58











    • @bogdan you're right. I misread the member function declarations.

      – eerorika
      Jul 1 at 11:10















    12















    this fails because std::cbegin() calls the .begin()




    To be more precise, std::cbegin calls std::begin, which in the generic overload calls c.begin.



    For what it's worth, it should be possible to fix gsl::span to return const iterator upon std::cbegin if the designers of gsl specify that there is a specialisation for the generic overload of std::cbegin for gsl::span that uses c.cbegin instead of std::begin, if that is the desired behaviour. I don't know their reasoning for not specifying such specialisation.



    As for reasoning for why std::cbegin uses std::begin, I do not know for fact either, but it does have the advantage of being able to support containers that have a c.begin member, but not a c.cbegin member, which can be seen as a less strict requirement, as it can be satisfied by custom containers written prior to C++11, when there was no convention of providing a c.cbegin member function.






    share|improve this answer

























    • "std::span does propagate constness" - does it? It doesn't look like that to me from how the member functions are declared. Looking at P0122, it seems that not propagating constness was a design goal.

      – bogdan
      Jul 1 at 10:58











    • @bogdan you're right. I misread the member function declarations.

      – eerorika
      Jul 1 at 11:10













    12












    12








    12








    this fails because std::cbegin() calls the .begin()




    To be more precise, std::cbegin calls std::begin, which in the generic overload calls c.begin.



    For what it's worth, it should be possible to fix gsl::span to return const iterator upon std::cbegin if the designers of gsl specify that there is a specialisation for the generic overload of std::cbegin for gsl::span that uses c.cbegin instead of std::begin, if that is the desired behaviour. I don't know their reasoning for not specifying such specialisation.



    As for reasoning for why std::cbegin uses std::begin, I do not know for fact either, but it does have the advantage of being able to support containers that have a c.begin member, but not a c.cbegin member, which can be seen as a less strict requirement, as it can be satisfied by custom containers written prior to C++11, when there was no convention of providing a c.cbegin member function.






    share|improve this answer
















    this fails because std::cbegin() calls the .begin()




    To be more precise, std::cbegin calls std::begin, which in the generic overload calls c.begin.



    For what it's worth, it should be possible to fix gsl::span to return const iterator upon std::cbegin if the designers of gsl specify that there is a specialisation for the generic overload of std::cbegin for gsl::span that uses c.cbegin instead of std::begin, if that is the desired behaviour. I don't know their reasoning for not specifying such specialisation.



    As for reasoning for why std::cbegin uses std::begin, I do not know for fact either, but it does have the advantage of being able to support containers that have a c.begin member, but not a c.cbegin member, which can be seen as a less strict requirement, as it can be satisfied by custom containers written prior to C++11, when there was no convention of providing a c.cbegin member function.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jul 1 at 11:09

























    answered Jul 1 at 0:04









    eerorikaeerorika

    98.2k6 gold badges78 silver badges149 bronze badges




    98.2k6 gold badges78 silver badges149 bronze badges












    • "std::span does propagate constness" - does it? It doesn't look like that to me from how the member functions are declared. Looking at P0122, it seems that not propagating constness was a design goal.

      – bogdan
      Jul 1 at 10:58











    • @bogdan you're right. I misread the member function declarations.

      – eerorika
      Jul 1 at 11:10

















    • "std::span does propagate constness" - does it? It doesn't look like that to me from how the member functions are declared. Looking at P0122, it seems that not propagating constness was a design goal.

      – bogdan
      Jul 1 at 10:58











    • @bogdan you're right. I misread the member function declarations.

      – eerorika
      Jul 1 at 11:10
















    "std::span does propagate constness" - does it? It doesn't look like that to me from how the member functions are declared. Looking at P0122, it seems that not propagating constness was a design goal.

    – bogdan
    Jul 1 at 10:58





    "std::span does propagate constness" - does it? It doesn't look like that to me from how the member functions are declared. Looking at P0122, it seems that not propagating constness was a design goal.

    – bogdan
    Jul 1 at 10:58













    @bogdan you're right. I misread the member function declarations.

    – eerorika
    Jul 1 at 11:10





    @bogdan you're right. I misread the member function declarations.

    – eerorika
    Jul 1 at 11:10













    9














    First, note that, per [tab:container.req]:




    Expression: a.cbegin()



    Return type: const_­iterator



    Operational semantics: const_­cast<​X const&​>(a)​.begin();



    Complexity: constant




    Therefore, gsl::span is not a container at all. cbegin and cend are designed to work with containers. There are some exceptions (arrays, initializer_list) that require special care, but apparently the standard library cannot mention something like gsl::span.



    Second, it is LWG 2128 that introduced global cbegin and cend. Let's see what the relevant part says:




    Implement std::cbegin/cend() by calling std::begin/end(). This has
    numerous advantages:



    • It automatically works with arrays, which is the whole point of these non-member functions.


    • It works with C++98/03-era user containers, written before cbegin/cend() members were invented.


    • It works with initializer_list, which is extremely minimal and lacks cbegin/cend() members.


    • [container.requirements.general]
      guarantees that this is equivalent to calling cbegin/cend() members.




    Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.






    share|improve this answer



























      9














      First, note that, per [tab:container.req]:




      Expression: a.cbegin()



      Return type: const_­iterator



      Operational semantics: const_­cast<​X const&​>(a)​.begin();



      Complexity: constant




      Therefore, gsl::span is not a container at all. cbegin and cend are designed to work with containers. There are some exceptions (arrays, initializer_list) that require special care, but apparently the standard library cannot mention something like gsl::span.



      Second, it is LWG 2128 that introduced global cbegin and cend. Let's see what the relevant part says:




      Implement std::cbegin/cend() by calling std::begin/end(). This has
      numerous advantages:



      • It automatically works with arrays, which is the whole point of these non-member functions.


      • It works with C++98/03-era user containers, written before cbegin/cend() members were invented.


      • It works with initializer_list, which is extremely minimal and lacks cbegin/cend() members.


      • [container.requirements.general]
        guarantees that this is equivalent to calling cbegin/cend() members.




      Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.






      share|improve this answer

























        9












        9








        9







        First, note that, per [tab:container.req]:




        Expression: a.cbegin()



        Return type: const_­iterator



        Operational semantics: const_­cast<​X const&​>(a)​.begin();



        Complexity: constant




        Therefore, gsl::span is not a container at all. cbegin and cend are designed to work with containers. There are some exceptions (arrays, initializer_list) that require special care, but apparently the standard library cannot mention something like gsl::span.



        Second, it is LWG 2128 that introduced global cbegin and cend. Let's see what the relevant part says:




        Implement std::cbegin/cend() by calling std::begin/end(). This has
        numerous advantages:



        • It automatically works with arrays, which is the whole point of these non-member functions.


        • It works with C++98/03-era user containers, written before cbegin/cend() members were invented.


        • It works with initializer_list, which is extremely minimal and lacks cbegin/cend() members.


        • [container.requirements.general]
          guarantees that this is equivalent to calling cbegin/cend() members.




        Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.






        share|improve this answer













        First, note that, per [tab:container.req]:




        Expression: a.cbegin()



        Return type: const_­iterator



        Operational semantics: const_­cast<​X const&​>(a)​.begin();



        Complexity: constant




        Therefore, gsl::span is not a container at all. cbegin and cend are designed to work with containers. There are some exceptions (arrays, initializer_list) that require special care, but apparently the standard library cannot mention something like gsl::span.



        Second, it is LWG 2128 that introduced global cbegin and cend. Let's see what the relevant part says:




        Implement std::cbegin/cend() by calling std::begin/end(). This has
        numerous advantages:



        • It automatically works with arrays, which is the whole point of these non-member functions.


        • It works with C++98/03-era user containers, written before cbegin/cend() members were invented.


        • It works with initializer_list, which is extremely minimal and lacks cbegin/cend() members.


        • [container.requirements.general]
          guarantees that this is equivalent to calling cbegin/cend() members.




        Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jul 1 at 1:03









        L. F.L. F.

        4,6033 gold badges16 silver badges41 bronze badges




        4,6033 gold badges16 silver badges41 bronze badges



























            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%2f56828691%2fwhy-does-stdcbegin-not-call-cbegin-on-the-container%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

            Grendel Contents Story Scholarship Depictions Notes References Navigation menu10.1093/notesj/gjn112Berserkeree

            Area configuration aggregation error after install Porto themeMagento 2.1 CE Installed but front/backend not loading/workingCSS not loading on page within Magento 2 pageCannot install module in Magento 2no commands defined in the “setup” namespace. in Magento2Magento 2: Static files are present but shows 404Why do i have to always run the commands to clean cache in Magento 2.1.8?Failure reason: 'Unable to unserialize value.'Error 500 after magento migrationIn production mode the site does not loadMagento 2 : Error 500 after installing

            Middle Expansion Olielle Resaix Definition: Uttering songs of triumph shouting with joy triumphant exulting Sejunction Journal 붙다 달 고급 품목 외출 The stretch trades the screeching tin. Definition: The act of speaking with a drawl a drawl Cough Sand Definition: An uproar a quarrel a noisy outbreak Shake Iron Publicize Horse House Baby 사과 Resaix Flaggy Jelly Temporary Unequaled Puppet A drop in the bucket Shrew 성격 회원 성질 미팅 The burn frames the tacky quality. Materialistic The smoke reduces the way. Yammoe Nondescript Cheek 얼굴 배 약하다 날리다 타다 The illegal country shows the iron. Help Rule Drearien Smoke Teaching Meaty Wasp Abraham Lincoln Jaws 진심 수리하다 Size Cork Idea Convert Think Lark John Lennon 거울 청소 군 추천하다 아이스크림