From: Grayham on
On Sun, 31 Jan 2010 19:36:27 +0000, Richard Heathfield wrote:

> Grayham wrote:
>
> <snip>
>
>> return !(isalnum(c)||
>> find(url_ch.begin(), url_ch.end(), c) != url_ch.end());
>>
>> My problem with this code is the "!= url_ch.end()" at the end of the
>> statement. This to me suggest a conditional situation normally applied
>> to a "while", "if" or "for" statement.
>
> The != operator takes two operands (call them X and Y, so the call is X
> != Y, okay?), and applies the following logic: if the two operands are
> equal, != yields the result 0. Otherwise, it yields the result 1. Yes,
> it's normally used in if(), while(), etc, but that's not written in
> stone.
>
> Try running this program:
>
> #include <stdio.h>
>
> int main(void)
> {
> int i;
> int j;
>
> printf(" 0 1 2 3 4\n");
> printf(" -----------\n");
>
> for(i = 0; i < 5; i++)
> {
> printf("%d", i);
>
> for(j = 0; j < 5; j++)
> {
> printf(" %d", i != j);
> }
> putchar('\n');
> }
>
> return 0;
> }
>
> With any luck, a light will go "bing" in your head (or possibly a sound
> will flash!), and you'll understand. Otherwise, check back.

Hello Richard.

I understand your example but as with Alfs example it's not made the
statement any clearer for me.
I understand conditional checks and comparisons I just don't see why it
is necessary here.


The "find" funtion has it's two iterators and the value to check for
which should be sufficient to return a result.
So why is it checking for the end of the container "!= url_ch.end()".
I don't see why that is a requirement as we are not stepping through
container. The "find" function steps through the container but that's
contained within the "find" function isn't it?

I hope I am making myself clearer.

Thanks for your help so far
Grayham



From: Alf P. Steinbach on
* Grayham:
> On Sun, 31 Jan 2010 19:36:27 +0000, Richard Heathfield wrote:
>
>> Grayham wrote:
>>
>> <snip>
>>
>>> return !(isalnum(c)||
>>> find(url_ch.begin(), url_ch.end(), c) != url_ch.end());
>>>
>>> My problem with this code is the "!= url_ch.end()" at the end of the
>>> statement. This to me suggest a conditional situation normally applied
>>> to a "while", "if" or "for" statement.
>> The != operator takes two operands (call them X and Y, so the call is X
>> != Y, okay?), and applies the following logic: if the two operands are
>> equal, != yields the result 0. Otherwise, it yields the result 1. Yes,
>> it's normally used in if(), while(), etc, but that's not written in
>> stone.
>>
>> Try running this program:
>>
>> #include <stdio.h>
>>
>> int main(void)
>> {
>> int i;
>> int j;
>>
>> printf(" 0 1 2 3 4\n");
>> printf(" -----------\n");
>>
>> for(i = 0; i < 5; i++)
>> {
>> printf("%d", i);
>>
>> for(j = 0; j < 5; j++)
>> {
>> printf(" %d", i != j);
>> }
>> putchar('\n');
>> }
>>
>> return 0;
>> }
>>
>> With any luck, a light will go "bing" in your head (or possibly a sound
>> will flash!), and you'll understand. Otherwise, check back.
>
> Hello Richard.
>
> I understand your example but as with Alfs example it's not made the
> statement any clearer for me.
> I understand conditional checks and comparisons I just don't see why it
> is necessary here.
>
>
> The "find" funtion has it's two iterators and the value to check for
> which should be sufficient to return a result.
> So why is it checking for the end of the container "!= url_ch.end()".
> I don't see why that is a requirement as we are not stepping through
> container. The "find" function steps through the container but that's
> contained within the "find" function isn't it?
>
> I hope I am making myself clearer.
>
> Thanks for your help so far
> Grayham

Perhaps rewrite the thing using a helper function:

bool occurs_in( std::string const& s, char const c )
{
bool const found =
(std::find( s.begin(), s.end(), c ) != s.end());
return found;
}

...
return !(isalnum( c ) || occurs_in( url_ch, c ));


Does that help?

Disclaimer: I haven't put that code through a compiler.


Cheers & hth.,

- Alf
From: Ben Bacarisse on
Grayham <no(a)spam_for_me.com> writes:
<snip>
>> Grayham wrote:
>>
>> <snip>
>>
>>> return !(isalnum(c)||
>>> find(url_ch.begin(), url_ch.end(), c) != url_ch.end());
>>>
>>> My problem with this code is the "!= url_ch.end()" at the end of the
>>> statement. This to me suggest a conditional situation normally applied
>>> to a "while", "if" or "for" statement.
<snip>
> I understand your example but as with Alfs example it's not made the
> statement any clearer for me.
> I understand conditional checks and comparisons I just don't see why it
> is necessary here.
>
>
> The "find" funtion has it's two iterators and the value to check for
> which should be sufficient to return a result.

It is indeed enough. find returns the position of the supplied value
between the first iterator and (but not including) the second. It
returns this position as an iterator value.

> So why is it checking for the end of the container "!=
> url_ch.end()".

What should find return if the value is *not* present? The find
function must return a value of the right type, so it can't for
example just return the string "not there".

The solution chosen by the STL is that it returns an iterator value
that can't be where the value was found. The only possible choice for
this special "not there" iterator value is the second iterator it was
presented with. This must be a valid iterator, but it also can't be
where the value was found because find never looks there.

In simpler words, find(i1, i2, c) == i2 means that c was *not* found
and find(i1, i2, c) != i2 means that is was.

> I don't see why that is a requirement as we are not stepping through
> container. The "find" function steps through the container but that's
> contained within the "find" function isn't it?

It is just a way to signal a negative result.

> I hope I am making myself clearer.

Likewise.

--
Ben.
From: Richard Heathfield on
Grayham wrote:

<snip>

> The "find" funtion has it's two iterators and the value to check for
> which should be sufficient to return a result.

Yes. That result will be url_ch.end() if the character is not found in
the string.

> So why is it checking for the end of the container "!= url_ch.end()".

To see whether the character is there.

> I don't see why that is a requirement as we are not stepping through
> container.

What do you think "find" does?

> The "find" function steps through the container but that's
> contained within the "find" function isn't it?

Yes, but it has to report its result somehow. If it can't find what it's
looking for, it returns end(), so that you know the character was not
found even though it looked all the way through to the end.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
From: Ben Cottrell on
Grayham wrote:
> Hello All
>
> I have been working my way through Accelerated c++ and have so far found
> it enjoyable interesting. I have currently just finished reading chapter
> 6 and there is one part I just can't get my head around. It's on page
> 107, last example.
>
> This Lines:
> return !(isalnum(c)||
> find(url_ch.begin(), url_ch.end(), c) != url_ch.end());

There are several different things going on in that expression; would it
help to mentally break that line down into two separate expressions?
specifically, determining the outcome of find before reaching the return
statement.

std::string::const_iterator i =
find(url_ch.begin(), url_ch.end(), c);
return !(isalnum(c) || i != url_ch.end());

I happen to have the book in front of me, I can see that there's a
similar example using find_if on pg 103/104, which makes use of the (i
!= str.end()) construct and seems to explain in more detail about the
use of an iterator as a return value.