Query regd. validity of a C++ program

F

frame

Hi,

The other day, I was experimenting with Predicates and STL and came
across a gotcha with the following program. The objective of the
program is to remove those strings, from a vector of strings, whose
size is of atleast a specified length (here 5) and contains atleast a
specified number of punctuation characters, excluding '@' (here 2).
There are 3 classes: Length and NumberOfSpecialChars in 'Parameters'
namespace (which are just wrappers around 'unsigned long') and
SpecialStringChecker in 'Processor' namespace. The problem, I am
facing, is the following program isn't getting complied under both
GNU's 'g++' and SUN Studio's 'CC'. Both are trying to convert
std::basic_string<...> to `Parameters::Length' (Don't know, why?) in
the remove_if(...) call. Interestingly, the program gets complied and
runs as expected if the commented lines are substituted for the
following uncommented parts. I am not sure, why are the compliers
reporting a problem with user-defined types (Length and
NumberOfSpecialChars), but not for a fundamental type (unsigned long)
or am I blowing this somewhere?

#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>
#include <iterator>
#include <ctype.h>

namespace Parameters{

class Length{
unsigned long length_;
public:
explicit Length(const unsigned long& length): length_(length) {}
operator unsigned long() const{
return length_;
}
};

class NumberOfSpecialChars{
unsigned long numberOfSpecialChars_;
public:
explicit NumberOfSpecialChars(const unsigned long&
numberOfSpecialChars):
numberOfSpecialChars_(numberOfSpecialChars) {}
operator unsigned long() const{
return numberOfSpecialChars_;
}
};

}

namespace Processor{

using namespace Parameters;
using namespace std;

class SpecialStringChecker{
Length length_;
NumberOfSpecialChars numberOfSpecialChars_;
public:
bool operator()(const string& s) const{
if(s.length() >= (unsigned long)(length_))
{
unsigned long matches = count_if(s.begin(), s.end(), *this);

if(matches >= (unsigned long)(numberOfSpecialChars_))
return true;
}
return false;
}
bool operator()(const char& c) const{
if(ispunct(c) && c !='@')
return true;
return false;
}
/*explicit SpecialStringChecker(const unsigned long& length,
const unsigned long& numberOfSpecialChars):
length_(length),
numberOfSpecialChars_(numberOfSpecialChars) {}*/
explicit SpecialStringChecker(const Length& length,
const NumberOfSpecialChars&
numberOfSpecialChars):
length_(length),
numberOfSpecialChars_(numberOfSpecialChars) {}
};

}

using namespace std;
using namespace Parameters;
using namespace Processor;

int main(int argc, char* argv[]){
vector<string> myStrVec;
myStrVec.push_back(string("%@text1&!#"));
myStrVec.push_back(string("text2"));
myStrVec.push_back(string("@text3"));
myStrVec.push_back(string("!#$%"));
unsigned long length=5, numberOfSpecialChars=2;
//SpecialStringChecker myStrChkr(length, numberOfSpecialChars);
SpecialStringChecker myStrChkr(Length(length),
NumberOfSpecialChars(numberOfSpecialChars));
vector<string>::iterator myStrVecItr;
myStrVecItr = remove_if(myStrVec.begin(), myStrVec.end(), myStrChkr);
myStrVec.erase(myStrVecItr, myStrVec.end());
copy(myStrVec.begin(), myStrVec.end(),
ostream_iterator<string>(cout,"\n"));
return 0;
}

//Thanks in advance to the takers!!
 
K

Kai-Uwe Bux

frame said:
Hi,

The other day, I was experimenting with Predicates and STL and came
across a gotcha with the following program. The objective of the
program is to remove those strings, from a vector of strings, whose
size is of atleast a specified length (here 5) and contains atleast a
specified number of punctuation characters, excluding '@' (here 2).
There are 3 classes: Length and NumberOfSpecialChars in 'Parameters'
namespace (which are just wrappers around 'unsigned long') and
SpecialStringChecker in 'Processor' namespace. The problem, I am
facing, is the following program isn't getting complied under both
GNU's 'g++' and SUN Studio's 'CC'. Both are trying to convert
std::basic_string<...> to `Parameters::Length' (Don't know, why?) in
the remove_if(...) call. Interestingly, the program gets complied and
runs as expected if the commented lines are substituted for the
following uncommented parts. I am not sure, why are the compliers
reporting a problem with user-defined types (Length and
NumberOfSpecialChars), but not for a fundamental type (unsigned long)
or am I blowing this somewhere?

#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>
#include <iterator>
#include <ctype.h>

namespace Parameters{

class Length{
unsigned long length_;
public:
explicit Length(const unsigned long& length): length_(length) {}
operator unsigned long() const{
return length_;
}
};

class NumberOfSpecialChars{
unsigned long numberOfSpecialChars_;
public:
explicit NumberOfSpecialChars(const unsigned long&
numberOfSpecialChars):
numberOfSpecialChars_(numberOfSpecialChars) {}
operator unsigned long() const{
return numberOfSpecialChars_;
}
};

}

namespace Processor{

using namespace Parameters;
using namespace std;

class SpecialStringChecker{
Length length_;
NumberOfSpecialChars numberOfSpecialChars_;
public:
bool operator()(const string& s) const{
if(s.length() >= (unsigned long)(length_))
{
unsigned long matches = count_if(s.begin(), s.end(), *this);

if(matches >= (unsigned long)(numberOfSpecialChars_))
return true;
}
return false;
}
bool operator()(const char& c) const{
if(ispunct(c) && c !='@')
return true;
return false;
}
/*explicit SpecialStringChecker(const unsigned long& length,
const unsigned long& numberOfSpecialChars):
length_(length),
numberOfSpecialChars_(numberOfSpecialChars) {}*/
explicit SpecialStringChecker(const Length& length,
const NumberOfSpecialChars&
numberOfSpecialChars):
length_(length),
numberOfSpecialChars_(numberOfSpecialChars) {}
};

}

using namespace std;
using namespace Parameters;
using namespace Processor;

int main(int argc, char* argv[]){
vector<string> myStrVec;
myStrVec.push_back(string("%@text1&!#"));
myStrVec.push_back(string("text2"));
myStrVec.push_back(string("@text3"));
myStrVec.push_back(string("!#$%"));
unsigned long length=5, numberOfSpecialChars=2;
//SpecialStringChecker myStrChkr(length, numberOfSpecialChars);
SpecialStringChecker
myStrChkr(Length(length),
NumberOfSpecialChars(numberOfSpecialChars));

The above appears to be parsed as a function declaration. Make that

SpecialStringChecker myStrChkr((Length(length)),
NumberOfSpecialChars(numberOfSpecialChars));

Note the additional pair of parentheses.
vector<string>::iterator myStrVecItr;
myStrVecItr = remove_if(myStrVec.begin(), myStrVec.end(), myStrChkr);
myStrVec.erase(myStrVecItr, myStrVec.end());
copy(myStrVec.begin(), myStrVec.end(),
ostream_iterator<string>(cout,"\n"));
return 0;
}

Best

Kai-Uwe Bux
 
F

frame

Kai-Uwe Bux said:
frame said:
Hi,

The other day, I was experimenting with Predicates and STL and came
across a gotcha with the following program. The objective of the
program is to remove those strings, from a vector of strings, whose
size is of atleast a specified length (here 5) and contains atleast a
specified number of punctuation characters, excluding '@' (here 2).
There are 3 classes: Length and NumberOfSpecialChars in 'Parameters'
namespace (which are just wrappers around 'unsigned long') and
SpecialStringChecker in 'Processor' namespace. The problem, I am
facing, is the following program isn't getting complied under both
GNU's 'g++' and SUN Studio's 'CC'. Both are trying to convert
std::basic_string<...> to `Parameters::Length' (Don't know, why?) in
the remove_if(...) call. Interestingly, the program gets complied and
runs as expected if the commented lines are substituted for the
following uncommented parts. I am not sure, why are the compliers
reporting a problem with user-defined types (Length and
NumberOfSpecialChars), but not for a fundamental type (unsigned long)
or am I blowing this somewhere?

#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>
#include <iterator>
#include <ctype.h>

namespace Parameters{

class Length{
unsigned long length_;
public:
explicit Length(const unsigned long& length): length_(length) {}
operator unsigned long() const{
return length_;
}
};

class NumberOfSpecialChars{
unsigned long numberOfSpecialChars_;
public:
explicit NumberOfSpecialChars(const unsigned long&
numberOfSpecialChars):
numberOfSpecialChars_(numberOfSpecialChars) {}
operator unsigned long() const{
return numberOfSpecialChars_;
}
};

}

namespace Processor{

using namespace Parameters;
using namespace std;

class SpecialStringChecker{
Length length_;
NumberOfSpecialChars numberOfSpecialChars_;
public:
bool operator()(const string& s) const{
if(s.length() >= (unsigned long)(length_))
{
unsigned long matches = count_if(s.begin(), s.end(), *this);

if(matches >= (unsigned long)(numberOfSpecialChars_))
return true;
}
return false;
}
bool operator()(const char& c) const{
if(ispunct(c) && c !='@')
return true;
return false;
}
/*explicit SpecialStringChecker(const unsigned long& length,
const unsigned long& numberOfSpecialChars):
length_(length),
numberOfSpecialChars_(numberOfSpecialChars) {}*/
explicit SpecialStringChecker(const Length& length,
const NumberOfSpecialChars&
numberOfSpecialChars):
length_(length),
numberOfSpecialChars_(numberOfSpecialChars) {}
};

}

using namespace std;
using namespace Parameters;
using namespace Processor;

int main(int argc, char* argv[]){
vector<string> myStrVec;
myStrVec.push_back(string("%@text1&!#"));
myStrVec.push_back(string("text2"));
myStrVec.push_back(string("@text3"));
myStrVec.push_back(string("!#$%"));
unsigned long length=5, numberOfSpecialChars=2;
//SpecialStringChecker myStrChkr(length, numberOfSpecialChars);
SpecialStringChecker
myStrChkr(Length(length),
NumberOfSpecialChars(numberOfSpecialChars));

The above appears to be parsed as a function declaration. Make that

SpecialStringChecker myStrChkr((Length(length)),
NumberOfSpecialChars(numberOfSpecialChars));

Note the additional pair of parentheses.
vector<string>::iterator myStrVecItr;
myStrVecItr = remove_if(myStrVec.begin(), myStrVec.end(), myStrChkr);
myStrVec.erase(myStrVecItr, myStrVec.end());
copy(myStrVec.begin(), myStrVec.end(),
ostream_iterator<string>(cout,"\n"));
return 0;
}

Best

Kai-Uwe Bux

Hey, Thanks a lot!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,740
Latest member
AdolphBig6

Latest Threads

Top