473,772 Members | 2,391 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Purpose of iterator_traits ::value_type

I tried to post this to comp.std.c++ some time ago, but for some reason
I aren't getting any automatic confirmation. I thought I would therefore
post it here.

Some time ago I submitted what is now Defect Report 484 on the standard
library. I'm beginning to wonder if I've just misunderstood the purpose
of iterator_traits ::value_type.

I constructed an input iterator where *i returns an int, but I set
iterator_traits ::value_type to bool. This should be valid, as operater*
only has to be convertable to the value_type. I then tried the following:

Have an input iterator iterate through the values {2,3,5}, and use
std::find to find a "true". On all the compilers I have access to this
failed, as the compilers simply compared the ints in the array to
boolean true, which returns false.

Reading the standard, I can't decide if this is correct behaviour or
not.. on one hand it looks like this is exactly what std::find claims to
do (find the first element where *a==true). On the other hand it seems
reasonable that an implementation can assume it can copy dereferenced
iterators in a variable of type iterator_traits ::value_type, and if it
did so the returned answer would be different.

Chris
Jul 22 '05 #1
8 2072
chris wrote:
I tried to post this to comp.std.c++ some time ago, but for some reason
I aren't getting any automatic confirmation. I thought I would therefore
post it here.

Some time ago I submitted what is now Defect Report 484 on the standard
library. I'm beginning to wonder if I've just misunderstood the purpose
of iterator_traits ::value_type.

I constructed an input iterator where *i returns an int, but I set
iterator_traits ::value_type to bool. This should be valid, as operater*
only has to be convertable to the value_type. I then tried the following:

Have an input iterator iterate through the values {2,3,5}, and use
std::find to find a "true". On all the compilers I have access to this
failed, as the compilers simply compared the ints in the array to
boolean true, which returns false.

Reading the standard, I can't decide if this is correct behaviour or
not.. on one hand it looks like this is exactly what std::find claims to
do (find the first element where *a==true). On the other hand it seems
reasonable that an implementation can assume it can copy dereferenced
iterators in a variable of type iterator_traits ::value_type, and if it
did so the returned answer would be different.


I am not sure where you get the latter (the "on the other hand") thing.
The *a has a particular type, and you defined it to be 'int' (I suppose
you do return corresponding value there). Unless there is no equality
operator for the type returned from operator*, there is no need to copy.

No implementation should perform unnecessary copying.

V
Jul 22 '05 #2
Victor Bazarov wrote:
chris wrote:
I tried to post this to comp.std.c++ some time ago, but for some
reason I aren't getting any automatic confirmation. I thought I would
therefore post it here.

Some time ago I submitted what is now Defect Report 484 on the
standard library. I'm beginning to wonder if I've just misunderstood
the purpose of iterator_traits ::value_type.

I constructed an input iterator where *i returns an int, but I set
iterator_traits ::value_type to bool. This should be valid, as
operater* only has to be convertable to the value_type. I then tried
the following:

Have an input iterator iterate through the values {2,3,5}, and use
std::find to find a "true". On all the compilers I have access to this
failed, as the compilers simply compared the ints in the array to
boolean true, which returns false.

Reading the standard, I can't decide if this is correct behaviour or
not.. on one hand it looks like this is exactly what std::find claims
to do (find the first element where *a==true). On the other hand it
seems reasonable that an implementation can assume it can copy
dereferenced iterators in a variable of type
iterator_traits ::value_type, and if it did so the returned answer
would be different.

I am not sure where you get the latter (the "on the other hand") thing.
The *a has a particular type, and you defined it to be 'int' (I suppose
you do return corresponding value there). Unless there is no equality
operator for the type returned from operator*, there is no need to copy.

No implementation should perform unnecessary copying.

No implementation should. However are you saying that NO implementation
should EVER copy a dereferenced iterator to a variable of type
iterator_traits ::value_type where the iterator is an input_iterator?
Because that seems like quite a strong condition, and I didn't realise
it was true.

Chris
Jul 22 '05 #3
chris wrote:
Victor Bazarov wrote:
chris wrote:
I tried to post this to comp.std.c++ some time ago, but for some
reason I aren't getting any automatic confirmation. I thought I would
therefore post it here.

Some time ago I submitted what is now Defect Report 484 on the
standard library. I'm beginning to wonder if I've just misunderstood
the purpose of iterator_traits ::value_type.

I constructed an input iterator where *i returns an int, but I set
iterator_traits ::value_type to bool. This should be valid, as
operater* only has to be convertable to the value_type. I then tried
the following:

Have an input iterator iterate through the values {2,3,5}, and use
std::find to find a "true". On all the compilers I have access to
this failed, as the compilers simply compared the ints in the array
to boolean true, which returns false.

Reading the standard, I can't decide if this is correct behaviour or
not.. on one hand it looks like this is exactly what std::find claims
to do (find the first element where *a==true). On the other hand it
seems reasonable that an implementation can assume it can copy
dereferenced iterators in a variable of type
iterator_traits ::value_type, and if it did so the returned answer
would be different.


I am not sure where you get the latter (the "on the other hand") thing.
The *a has a particular type, and you defined it to be 'int' (I suppose
you do return corresponding value there). Unless there is no equality
operator for the type returned from operator*, there is no need to copy.

No implementation should perform unnecessary copying.

No implementation should. However are you saying that NO implementation
should EVER copy a dereferenced iterator to a variable of type
iterator_traits ::value_type where the iterator is an input_iterator?
Because that seems like quite a strong condition, and I didn't realise
it was true.


I think the copying has to be approached on the case to case basis and
decided when such copying is in fact taking place. 'std::find' does not
seem one of those places, since its semantics are well defined.

I was thinking of a possible example where copying is necessary even with
'std::find', and the only thing comes to mind is the absence of operator==
for the type returned from operator*, and instead existence of operator==
for the 'iterator_trait s::value_type'. Since you have your example
environment completely set up, could you test it with

struct noequality { };
struct hasequality {
bool operator==(hase quality const&) const;
hasequality();
hasequality(noe quality); // parameterized c-tor
};

struct youriterator {
...
noequality operator *();
};

... iterator_traits <youriterator > {
typedef hasequality value_type;
...
};

Which should mean that 'youriterator' returns 'noequality', which is in
turn convertible to 'hasequality', which does have operator== defined.

I am interested to see if the compiler will force the conversion. I do
not expect it to, though. For the second exercise, remove the operator==
from the 'hasequality' and define a global one:

bool operator==(hase quality const&, hasequality const&);

For non-members user conversions of operands are tried during lookup.

See what I mean?

V
Jul 22 '05 #4
Victor Bazarov wrote:
chris wrote:
Victor Bazarov wrote:
chris wrote:

I tried to post this to comp.std.c++ some time ago, but for some
reason I aren't getting any automatic confirmation. I thought I
would therefore post it here.

Some time ago I submitted what is now Defect Report 484 on the
standard library. I'm beginning to wonder if I've just misunderstood
the purpose of iterator_traits ::value_type.

I constructed an input iterator where *i returns an int, but I set
iterator_traits ::value_type to bool. This should be valid, as
operater* only has to be convertable to the value_type. I then tried
the following:

Have an input iterator iterate through the values {2,3,5}, and use
std::find to find a "true". On all the compilers I have access to
this failed, as the compilers simply compared the ints in the array
to boolean true, which returns false.

Reading the standard, I can't decide if this is correct behaviour or
not.. on one hand it looks like this is exactly what std::find
claims to do (find the first element where *a==true). On the other
hand it seems reasonable that an implementation can assume it can
copy dereferenced iterators in a variable of type
iterator_traits ::value_type, and if it did so the returned answer
would be different.


I am not sure where you get the latter (the "on the other hand") thing.
The *a has a particular type, and you defined it to be 'int' (I suppose
you do return corresponding value there). Unless there is no equality
operator for the type returned from operator*, there is no need to copy.

No implementation should perform unnecessary copying.

No implementation should. However are you saying that NO
implementation should EVER copy a dereferenced iterator to a variable
of type iterator_traits ::value_type where the iterator is an
input_iterator? Because that seems like quite a strong condition, and
I didn't realise it was true.

I think the copying has to be approached on the case to case basis and
decided when such copying is in fact taking place. 'std::find' does not
seem one of those places, since its semantics are well defined.

Hmm.. I'm not convinced that's good enough. Saying "case by case basis"
is clearly no good with regards the standard (unless of course someone
goes through the whole standard, and does the case-by-case comparison).
I wonder if "convertabl e to T" should just be tightened a list, like
"one of const T, T, T&, const T&", or some such? Is that what was meant...

<snip example>
actually, this seems to work fine :)

Chris
Jul 22 '05 #5
chris wrote:
Victor Bazarov wrote:
chris wrote:
Victor Bazarov wrote:

chris wrote:

> I tried to post this to comp.std.c++ some time ago, but for some
> reason I aren't getting any automatic confirmation. I thought I
> would therefore post it here.
>
> Some time ago I submitted what is now Defect Report 484 on the
> standard library. I'm beginning to wonder if I've just
> misunderstood the purpose of iterator_traits ::value_type.
>
> I constructed an input iterator where *i returns an int, but I set
> iterator_traits ::value_type to bool. This should be valid, as
> operater* only has to be convertable to the value_type. I then
> tried the following:
>
> Have an input iterator iterate through the values {2,3,5}, and use
> std::find to find a "true". On all the compilers I have access to
> this failed, as the compilers simply compared the ints in the array
> to boolean true, which returns false.
>
> Reading the standard, I can't decide if this is correct behaviour
> or not.. on one hand it looks like this is exactly what std::find
> claims to do (find the first element where *a==true). On the other
> hand it seems reasonable that an implementation can assume it can
> copy dereferenced iterators in a variable of type
> iterator_traits ::value_type, and if it did so the returned answer
> would be different.

I am not sure where you get the latter (the "on the other hand") thing.
The *a has a particular type, and you defined it to be 'int' (I suppose
you do return corresponding value there). Unless there is no equality
operator for the type returned from operator*, there is no need to
copy.

No implementation should perform unnecessary copying.

No implementation should. However are you saying that NO
implementation should EVER copy a dereferenced iterator to a variable
of type iterator_traits ::value_type where the iterator is an
input_iterator? Because that seems like quite a strong condition, and
I didn't realise it was true.
I think the copying has to be approached on the case to case basis and
decided when such copying is in fact taking place. 'std::find' does not
seem one of those places, since its semantics are well defined.

Hmm.. I'm not convinced that's good enough. Saying "case by case basis"
is clearly no good with regards the standard (unless of course someone
goes through the whole standard, and does the case-by-case comparison).
I wonder if "convertabl e to T" should just be tightened a list, like
"one of const T, T, T&, const T&", or some such? Is that what was meant...


For every algorithm that has its semantics defined in the standard, there
is no need to use "case by case basis" approach. Just like with 'find',
those things shall not have copying (or, reverse, shall have copying) as
part of the overall algorithm, but they are already there. Such approach
will be needed (IMHO) for all cases outside the Standard, for which
semantics are either invented by the programmer or simply not mentioned in
the Standard.

OTOH, I am probably wrong again, and today I'm just too lazy to think any
harder...
<snip example>
actually, this seems to work fine :)


Well... Good! :-)

V
Jul 22 '05 #6
On Thu, 09 Dec 2004 17:13:19 +0000, chris <ca*@cs.york.ac .uk> wrote:
I tried to post this to comp.std.c++ some time ago, but for some reason
I aren't getting any automatic confirmation. I thought I would therefore
post it here.

Some time ago I submitted what is now Defect Report 484 on the standard
library. I'm beginning to wonder if I've just misunderstood the purpose
of iterator_traits ::value_type.

I constructed an input iterator where *i returns an int, but I set
iterator_trait s::value_type to bool. This should be valid, as operater*
only has to be convertable to the value_type.
But the "value type" of an iterator is defined to be the type of the
"value" *it. I assume by taking about the "value", we can drop
references desired. See 24.1/1. 24.3.1 seems to be pretty clear that
value_type must be *the* value type of the iterator, not any type T
over which the iterator meets the input iterator requirements. IMHO.
I then tried the following:

Have an input iterator iterate through the values {2,3,5}, and use
std::find to find a "true". On all the compilers I have access to this
failed, as the compilers simply compared the ints in the array to
boolean true, which returns false.

Reading the standard, I can't decide if this is correct behaviour or
not.. on one hand it looks like this is exactly what std::find claims to
do (find the first element where *a==true). On the other hand it seems
reasonable that an implementation can assume it can copy dereferenced
iterators in a variable of type iterator_traits ::value_type, and if it
did so the returned answer would be different.


Not if iterator_traits ::value_type is defined to be *the* value type
of the iterator, not just some type "T" over which it passes the
iterator requirements.

Tom
Jul 22 '05 #7
Tom Widmer wrote:
On Thu, 09 Dec 2004 17:13:19 +0000, chris <ca*@cs.york.ac .uk> wrote:

I tried to post this to comp.std.c++ some time ago, but for some reason
I aren't getting any automatic confirmation. I thought I would therefore
post it here.

Some time ago I submitted what is now Defect Report 484 on the standard
library. I'm beginning to wonder if I've just misunderstood the purpose
of iterator_traits ::value_type.

I constructed an input iterator where *i returns an int, but I set
iterator_trai ts::value_type to bool. This should be valid, as operater*
only has to be convertable to the value_type.

But the "value type" of an iterator is defined to be the type of the
"value" *it. I assume by taking about the "value", we can drop
references desired. See 24.1/1. 24.3.1 seems to be pretty clear that
value_type must be *the* value type of the iterator, not any type T
over which the iterator meets the input iterator requirements. IMHO.


I was getting my reading from:

24.4.1 1: "A class or a built-in type X satisfies the requirements of an
input iterator for the value type T..."

Table 72:

"*a convertible to T"

....

"value_type if the value type of the iterator"

So I read that *a has to be only convertable to T, and that *a does not
have to be the same type as iterator_traits ::value_type.

While we are on the subject of input iterators, out of interest what is
the opinion on the Note after table 72:

"Note: For input iterators, a==b does not imply ++a == ++b ...."

Actually, is ++a == ++b a well-defined statement??

If we look at ++r, then it looks like it is saying that the pre is "r is
dererferencable ", and the post containes "any copies of the previous
value of r are no longer required to be dereferenceable ".

Therefore I think that this statement is a) undefined and b) not helpful..

any thoughts? :)

Chris
Jul 22 '05 #8
On Fri, 10 Dec 2004 14:13:05 +0000, chris <ca*@cs.york.ac .uk> wrote:
"value_type if the value type of the iterator"

So I read that *a has to be only convertable to T, and that *a does not
have to be the same type as iterator_traits ::value_type.
Yeah, if you miss the very start of 24.1 then it does read that way.
But there definitely is a difference between the family of types, T,
that an iterator is a valid input iterator for, and the value type of
that iterator (which will of course be a member of the set of Ts).
While we are on the subject of input iterators, out of interest what is
the opinion on the Note after table 72:

"Note: For input iterators, a==b does not imply ++a == ++b ...."

Actually, is ++a == ++b a well-defined statement??
Nope, not in general, although it is well-formed at least.
If we look at ++r, then it looks like it is saying that the pre is "r is
dererferencabl e", and the post containes "any copies of the previous
value of r are no longer required to be dereferenceable ".

Therefore I think that this statement is a) undefined and b) not helpful..


Certainly agreed on the a) bit.

Tom
Jul 22 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
2738
by: Kitty | last post by:
Hi, everyone. Given a vector<int>, what is the fastest way to find out whether there is a repeated element in it? The result is just "true" or "false". Thanks. Kitty
3
1523
by: Lieven | last post by:
Is there a way in C++, given an iterator, I can get the container it's pointing to, in analogy of anIterator::value_type which gives the type of the elements of the container ?
6
3046
by: Daniel T. | last post by:
The line marked (1) below compiles fine and does exactly what I would expect, but the line marked (2) does not compile at all on my system. error: variable or field 'bar' declared void My question is, does the standard dictate that the value_type of a back_inserter is 'void'? If so, why? I would expect the value_type of a back_inserter to be the same as the value_type of the container it wraps.
1
2219
by: cesco | last post by:
Hi, I have a map container where the key_type is a pointer to a class and the value_type is an intenger. I'd like to apply the STL algorithm partial_sum to the value_type field of that map but I don't know how to do it. Probably I have to specify a functor as fourth argument of partial_sum but I don't know how to implement that. Can anyone help? Thanks and regards
6
1600
by: gexarchakos | last post by:
Hi there, Please give me at least a hint... I have a problem implementing a function object with parameters two iterators. That is: A class 'node' produces messages using a routing policy. The routing policy needs to take the node's neighbours and return a subset of them based on several criteria. Each message may have different routing policy. Thus, the policy should be specified while the new message is
4
1780
by: FabioAng | last post by:
Assuming I have this function: template<typename OutputIterator> void copy(const char* input, OutputIterator result) { while ( *input != NULL ) { *result = *input; ++result; ++input;
1
2095
by: antoanish | last post by:
Hello, My Requirement is 1. Copy data from iterator to an array ( array should be created dynamically within the function based on data_type of the data held by the iterator /container. ) 2. Copy data from array into iterator ( array should be created dynamically within the function based on data_type of the data held by the iterator /container. ) Implementation ----------------------- //copies data from begin to end of...
2
2383
by: Chris Forone | last post by:
hello group, is it possible to get the size of iterated object: "sizeof(typename iterator_traits<InputIterator>::value_type);" and NOT using dereferencing sizeof(*theIterator); ? thanks & hand, chris
6
3935
by: Peng Yu | last post by:
Hi, I'm wondering if the following assignment is lazy copy or not? Thanks, Peng std::vector<intv. v.push_back(1); v.push_back(2);
0
9619
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9454
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10261
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8934
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7460
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6713
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5354
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4007
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3609
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.