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;
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++
add a comment |
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++
1
for reference : "auto cbegin( const C& c )returns exactlystd::begin(c)"
– bolov
Jun 30 at 23:53
add a comment |
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++
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++
c++
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 exactlystd::begin(c)"
– bolov
Jun 30 at 23:53
add a comment |
1
for reference : "auto cbegin( const C& c )returns exactlystd::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
add a comment |
2 Answers
2
active
oldest
votes
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.
"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
add a comment |
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 callingstd::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 lackscbegin/cend()members.
[container.requirements.general]
guarantees that this is equivalent to callingcbegin/cend()members.
Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
"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
add a comment |
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.
"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
add a comment |
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.
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.
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
add a comment |
"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
add a comment |
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 callingstd::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 lackscbegin/cend()members.
[container.requirements.general]
guarantees that this is equivalent to callingcbegin/cend()members.
Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.
add a comment |
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 callingstd::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 lackscbegin/cend()members.
[container.requirements.general]
guarantees that this is equivalent to callingcbegin/cend()members.
Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.
add a comment |
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 callingstd::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 lackscbegin/cend()members.
[container.requirements.general]
guarantees that this is equivalent to callingcbegin/cend()members.
Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.
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 callingstd::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 lackscbegin/cend()members.
[container.requirements.general]
guarantees that this is equivalent to callingcbegin/cend()members.
Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.
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
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
1
for reference : "
auto cbegin( const C& c )returns exactlystd::begin(c)"– bolov
Jun 30 at 23:53