Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Why is this code complaining about constness?

Reply
Thread Tools

Why is this code complaining about constness?

 
 
markscottwright
Guest
Posts: n/a
 
      08-01-2007
I'm using visual studio 8, and the following code is failing. For the
life of me, I can't see what's wrong...

void myTest(std::string const& in)
{
using namespace std;
string::const_iterator lastNonWhitespace = find_if(in.rbegin(),
in.rend(), not1(ptr_fun(isspace)));
}

The error is:
strutils.cpp|226 error 2440| 'initializing' : cannot convert from
'std::reverse_iterator<_RanIt>' to
'std::_String_const_iterator<_Elem,_Traits,_Alloc> '
|| with
|| [
||
_RanIt=std::_String_const_iterator<char,std::char_ traits<char>,std::allocator<char>>
|| ]
|| and
|| [
|| _Elem=char,
|| _Traits=std::char_traits<char>,
|| _Alloc=std::allocator<char>
|| ]
|| No constructor could take the source type, or constructor
overload resolution was ambiguous

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      08-01-2007
markscottwright wrote:
> I'm using visual studio 8, and the following code is failing. For the
> life of me, I can't see what's wrong...
>
> void myTest(std::string const& in)
> {
> using namespace std;
> string::const_iterator lastNonWhitespace = find_if(in.rbegin(),


Did you mean to declare it 'string::const_reverse_iterator'? If
not, you might want to look into the 'base' member, as in

string::const_iterator lastNonWhitspace = find_if(...) . base();

> in.rend(), not1(ptr_fun(isspace)));
> }
>
> The error is:
> strutils.cpp|226 error 2440| 'initializing' : cannot convert from
> 'std::reverse_iterator<_RanIt>' to
> 'std::_String_const_iterator<_Elem,_Traits,_Alloc> '
>>> with
>>> [
>>>

> _RanIt=std::_String_const_iterator<char,std::char_ traits<char>,std::allocator<char>>
>>> ]
>>> and
>>> [
>>> _Elem=char,
>>> _Traits=std::char_traits<char>,
>>> _Alloc=std::allocator<char>
>>> ]
>>> No constructor could take the source type, or constructor

> overload resolution was ambiguous


--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
Bo Persson
Guest
Posts: n/a
 
      08-01-2007
markscottwright wrote:
:: I'm using visual studio 8, and the following code is failing. For
:: the life of me, I can't see what's wrong...
::
:: void myTest(std::string const& in)
:: {
:: using namespace std;
:: string::const_iterator lastNonWhitespace = find_if(in.rbegin(),
:: in.rend(), not1(ptr_fun(isspace)));
:: }
::
:: The error is:
:: strutils.cpp|226 error 2440| 'initializing' : cannot convert from
:: 'std::reverse_iterator<_RanIt>' to
:: 'std::_String_const_iterator<_Elem,_Traits,_Alloc> '

It says it all right here -- rbegin() returns a reverse_iterator (and
so will find_if), which cannot be assigned to a const_iterator. They
are just different types, with no conversion defined.

Have you looked into std::string's member functions find_first_of,
find_last_not_of, etc?


Bo Persson


 
Reply With Quote
 
markscottwright
Guest
Posts: n/a
 
      08-01-2007
On Aug 1, 1:36 pm, "Victor Bazarov" <(E-Mail Removed)> wrote:
> markscottwright wrote:
> > I'm using visual studio 8, and the following code is failing. For the
> > life of me, I can't see what's wrong...

>
> > void myTest(std::string const& in)
> > {
> > using namespace std;
> > string::const_iterator lastNonWhitespace = find_if(in.rbegin(),

>
> Did you mean to declare it 'string::const_reverse_iterator'? If
> not, you might want to look into the 'base' member, as in
>
> string::const_iterator lastNonWhitspace = find_if(...) . base();
>
>
>
> > in.rend(), not1(ptr_fun(isspace)));
> > }

>
> > The error is:
> > strutils.cpp|226 error 2440| 'initializing' : cannot convert from
> > 'std::reverse_iterator<_RanIt>' to
> > 'std::_String_const_iterator<_Elem,_Traits,_Alloc> '
> >>> with
> >>> [

>
> > _RanIt=std::_String_const_iterator<char,std::char_ traits<char>,std::allocator<char>>
> >>> ]
> >>> and
> >>> [
> >>> _Elem=char,
> >>> _Traits=std::char_traits<char>,
> >>> _Alloc=std::allocator<char>
> >>> ]
> >>> No constructor could take the source type, or constructor

> > overload resolution was ambiguous

>
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask


Thanks - that was indeed my problem. I needed to take the resulting
reverse_iterator and get its iterator through the base() method.
Thanks for the help.

Mark

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      08-02-2007
On Aug 1, 8:10 pm, markscottwright <(E-Mail Removed)> wrote:
> I'm using visual studio 8, and the following code is failing. For the
> life of me, I can't see what's wrong...


> void myTest(std::string const& in)
> {
> using namespace std;
> string::const_iterator lastNonWhitespace = find_if(in.rbegin(),
> in.rend(), not1(ptr_fun(isspace)));


Victor has pointed out one of the errors. But the last argument
to find_if can't be correct either. First, of course, because
one of the isspace functions is a template, so argument type
deduction fails if it is visible. (Of course, the one that it a
template takes two arguments, so can't be used here. But the
compiler can't know that until it's instantiated the template,
and it can't instantiate the template until it has chosen the
correct isspace.) And secondly, because calling the one
argument version of isspace (from <cctype> or <ctype.h>) with
the char resulting from the referencing of
std::string::const_reverse_iterator is undefined behavior.

> }


--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
markscottwright
Guest
Posts: n/a
 
      08-02-2007
On Aug 2, 4:23 am, James Kanze <(E-Mail Removed)> wrote:
> On Aug 1, 8:10 pm, markscottwright <(E-Mail Removed)> wrote:
>
> > I'm using visual studio 8, and the following code is failing. For the
> > life of me, I can't see what's wrong...
> > void myTest(std::string const& in)
> > {
> > using namespace std;
> > string::const_iterator lastNonWhitespace = find_if(in.rbegin(),
> > in.rend(), not1(ptr_fun(isspace)));

>
> Victor has pointed out one of the errors. But the last argument
> to find_if can't be correct either. First, of course, because
> one of the isspace functions is a template, so argument type
> deduction fails if it is visible. (Of course, the one that it a
> template takes two arguments, so can't be used here. But the
> compiler can't know that until it's instantiated the template,
> and it can't instantiate the template until it has chosen the
> correct isspace.) And secondly, because calling the one
> argument version of isspace (from <cctype> or <ctype.h>) with
> the char resulting from the referencing of
> std::string::const_reverse_iterator is undefined behavior.
>
> > }

>
> --
> James Kanze (GABI Software) email:(E-Mail Removed)
> Conseils en informatique orientée objet/
> Beratung in objektorientierter Datenverarbeitung
> 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


C++. Sigh.

So, what *is* the correct way to find the last non-whitespace
character in a string?


 
Reply With Quote
 
BobR
Guest
Posts: n/a
 
      08-02-2007

markscottwright <(E-Mail Removed)> wrote in message...

>So, what *is* the correct way to find the last non-whitespace
>character in a string?


std::string test271("hello, my name is mud! ");
size_t indx( test271.find_last_not_of( ' ' ) );
if( indx != test271.npos ){
cout<<"indx="<<indx<<std::endl;
cout<<"test271.substr(indx)="
<<test271.substr(indx)<<std::endl;
cout<<"test271.at( indx )="
<<test271.at( indx )<<std::endl;
} // if()

/* -out-
indx=21
test271.substr(indx)=! // which is "! ".
test271.at( indx )=!
*/

That just finds a 'space' char.
Look up the other overloads of std::string find*** for more.

http://www.dinkumware.com/manuals/.

--
Bob R
POVrookie


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      08-03-2007
On Aug 2, 9:30 pm, markscottwright <(E-Mail Removed)> wrote:
> On Aug 2, 4:23 am, James Kanze <(E-Mail Removed)> wrote:
> > On Aug 1, 8:10 pm, markscottwright <(E-Mail Removed)> wrote:


> > > I'm using visual studio 8, and the following code is failing. For the
> > > life of me, I can't see what's wrong...
> > > void myTest(std::string const& in)
> > > {
> > > using namespace std;
> > > string::const_iterator lastNonWhitespace = find_if(in.rbegin(),
> > > in.rend(), not1(ptr_fun(isspace)));


> > Victor has pointed out one of the errors. But the last argument
> > to find_if can't be correct either. First, of course, because
> > one of the isspace functions is a template, so argument type
> > deduction fails if it is visible. (Of course, the one that it a
> > template takes two arguments, so can't be used here. But the
> > compiler can't know that until it's instantiated the template,
> > and it can't instantiate the template until it has chosen the
> > correct isspace.) And secondly, because calling the one
> > argument version of isspace (from <cctype> or <ctype.h>) with
> > the char resulting from the referencing of
> > std::string::const_reverse_iterator is undefined behavior.


> > > }


> C++. Sigh.


Don't blame C++ for this one. We just inherited it from C.

> So, what *is* the correct way to find the last non-whitespace
> character in a string?


As usual, there is no one correct way. A lot depends on
context. I do a fair amount of text processing from time to
time, so I've written library classes to wrap the functions in
<locale>, particularly those in the ctype facet. For a one time
use, however, that's a lot more than you'd probably want to
type; if internationalization isn't an issue (or if you're happy
to always use the global locale), then just writting something
like:

struct IsWhite
{
bool operator()( char ch ) const
{
return isspace( static_cast< unsigned char >( ch ) ) ;
}
} ;

and using it as your predicate (possibly with std::not1), should
be largely sufficient.

Officially, of course, you're supposed to use the std::ctype
facet defined in <local>. But everything in <local> is pretty
much a horror with regards to ease of use, so unless you really
need full internationalization, something like the above is much
simpler, and just as good. Just remember to cast any char to
unsigned char before invoking any function in
<ctype.h>/<cctype>, and you should be OK.

And also: be wary of passing the address of a function to a
template function (e.g. as predicate or functional object).
Type deduction and function overload resolution don't always
work very well in such cases: basically, type deduction needs to
know the results of function overload resolution, and vice
versa, so the compiler gives up, and says ambiguous. This is
especially true in cases like the above, because the overloaded
functions are found in <locale>, which may or may not be
indirectly included. It's a bit of a pain to have to write
small classes like the above, but it avoids problems in the long
run.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
convertDateTime keeps complaining about the format KevinLEdwards@gmail.com Java 2 02-19-2006 12:38 AM
why is abs function complaining about double? sandwich_eater@hotmail.com C++ 6 07-03-2005 05:45 PM
Apache SOAP on Tomcat complaining about serializer codehead Java 3 06-13-2005 07:28 AM
To those few complaining about DVDFile... Brian The Demolition Man Little DVD Video 5 11-15-2004 06:57 PM



Advertisments