STL conatainer with a comparison function, what is the standard?

T

tjgable

I have some code that builds fine on .Net 2001(?).. VC++ 7.0. But with
gcc 3.42 in MinGW and MS VC++ 6.0 it does not. I can understand VC++
not working, but isn't gcc standard yet? Here is the code, from what I
can tell from searching around, the function in the third term is ok in
some compilers, but not others. Can anyone recommend a free compliant
compiler, is Open Watcom?

vector<CIniFile::Record> content; // Used to hold the sorted content
vector<CIniFile::Record> sections = GetSections(FileName); // Get a
list of Sections
if(!sections.empty()) // Is there anything to process?
{
if(Descending) // Descending or Ascending?
std::sort(sections.begin(), sections.end(),
DescendingSectionSort());
else // Sort the Sections
std::sort(sections.begin(), sections.end(),
AcendingSectionSort());
.....
}
 
P

Phil Staite

Without seeing the declarations for DescendingSectionSort and
AcendingSectionSort... No idea what may be wrong.
 
L

Larry I Smith

I have some code that builds fine on .Net 2001(?).. VC++ 7.0. But with
gcc 3.42 in MinGW and MS VC++ 6.0 it does not. I can understand VC++
not working, but isn't gcc standard yet? Here is the code, from what I
can tell from searching around, the function in the third term is ok in
some compilers, but not others. Can anyone recommend a free compliant
compiler, is Open Watcom?

vector<CIniFile::Record> content; // Used to hold the sorted content
vector<CIniFile::Record> sections = GetSections(FileName); // Get a
list of Sections
if(!sections.empty()) // Is there anything to process?
{
if(Descending) // Descending or Ascending?
std::sort(sections.begin(), sections.end(),
DescendingSectionSort());
else // Sort the Sections
std::sort(sections.begin(), sections.end(),
AcendingSectionSort());
....
}

Hmm, 'gcc' (you actually use 'g++', not 'gcc', to compile C++ progs)
is standards compliant. The 3rd arg to 'sort' must be a function
that itself takes 2 args. Your 'sort' statements are incorrect.
Here's a snip from the docs for 'sort':

<quote>
sort

template<class RanIt>
void sort(RanIt first, RanIt last);

template<class RanIt, class Pred>
void sort(RanIt first, RanIt last, Pred pr);

The first template function reorders the sequence designated by
iterators in the range [first, last) to form a sequence ordered
by operator<. Thus, the elements are sorted in ascending order.

The function evaluates the ordering predicate X < Y at most
ceil((last - first) * log(last - first)) times.

The second template function behaves the same, except that it
replaces operator<(X, Y) with pr(X, Y)
</quote>

You are using the 'second template' function; so, your
DescendingSectionSort() and AscendingSectionSort() must
each take 2 args of type CIniFile::Record (or ref's to same).

Somewhere should be something like this:

bool DescendingSectionSort(const CIniFile::Record& X,
const CIniFile::Record& Y)
{
// compare code here
}

The same type of code for AscendingSectionSort() goes here...

Then your sort statements would look like this:

std::sort(sections.begin(), sections.end(),
DescendingSectionSort);

Here's a complete simple example:

#include <iostream>
#include <vector>

struct Stuff
{
int a;
double b;

Stuff(int ia, double fb) : a(ia), b(fb) {}
};

bool DescStuff(const Stuff& s1, const Stuff& s2)
{
return s1.a > s2.a;
}

int main()
{
std::vector<Stuff> stuff;

stuff.push_back(Stuff(1, 1.0));
stuff.push_back(Stuff(2, 2.0));
stuff.push_back(Stuff(3, 3.0));

// sort 'stuff' into descending order on 'a'
std::sort(stuff.begin(), stuff.end(), DescStuff);

std::vector<Stuff>::iterator it;

// print the sorted 'stuff'
for (it = stuff.begin(); it != stuff.end(); it++)
std::cout << (*it).a << std::endl;

return 0;
}

Regards,
Larry
 
L

Larry I Smith

I have some code that builds fine on .Net 2001(?).. VC++ 7.0. But with
gcc 3.42 in MinGW and MS VC++ 6.0 it does not. I can understand VC++
not working, but isn't gcc standard yet? Here is the code, from what I
can tell from searching around, the function in the third term is ok in
some compilers, but not others. Can anyone recommend a free compliant
compiler, is Open Watcom?

vector<CIniFile::Record> content; // Used to hold the sorted content
vector<CIniFile::Record> sections = GetSections(FileName); // Get a
list of Sections
if(!sections.empty()) // Is there anything to process?
{
if(Descending) // Descending or Ascending?
std::sort(sections.begin(), sections.end(),
DescendingSectionSort());
else // Sort the Sections
std::sort(sections.begin(), sections.end(),
AcendingSectionSort());
....
}

As I said in my earlier post, the syntax of your "sort"
statements is incorrect.

The way you have the "std::sort" statements written, with
"DescendingSectionSort()" and "AscendingSectionSort()",
should produce a compile-time error. There should not
be any "()" following "DescendingSectionSort" and
"AscendingSectionSort" in the "std::sort" statements.

The code should be:

if(Descending) // Descending or Ascending?
std::sort(sections.begin(), sections.end(),
DescendingSectionSort );
else // Sort the Sections
std::sort(sections.begin(), sections.end(),
AcendingSectionSort );

So, it is ".Net 2001(?).. VC++ 7.0" that is wrong (non-Standard),
and VC++ 6.0 and GCC which are correct (Standard).

Regards,
Larry
 
P

Phil Staite

Larry I Smith said:
(e-mail address removed) wrote:
As I said in my earlier post, the syntax of your "sort"
statements is incorrect.

They could be correct, if for example DecendingSectionSort were a functor,
defined something like:


struct DecendingSectionSort : public std::binary_function<CIniFile::Record,
CIniFile::Record, bool>
{
bool operator()(CIniFile::Record& lhs, const CIniFile::Record& rhs)
const
{
// compare lhs and rhs here and return ordering indicator
}
};
 
L

Larry I Smith

Phil said:
They could be correct, if for example DecendingSectionSort were a functor,
defined something like:


struct DecendingSectionSort : public std::binary_function<CIniFile::Record,
CIniFile::Record, bool>
{
bool operator()(CIniFile::Record& lhs, const CIniFile::Record& rhs)
const
{
// compare lhs and rhs here and return ordering indicator
}
};

Yes, you are correct. Since GCC fails to compile the code,
I suspect that the OP's functions are not functors.

Regards,
Larry
 
T

tjgable

They are local functions, not functors. .Net compiles fine, gcc(g++)
does not.

I have another function that will cause the same compile error.

bool SortCriterion(fooObject * O1, fooObject * O2) {

if (O1->GetFoo() <= O2->GetFoo())
return FALSE;
else
return TRUE;
};

This is then fed to sort as the third arguement. As I understand it the
standard can take a function like the one above as the compare
arguement, why does g++ not like it?
 
L

Larry I Smith

They are local functions, not functors. .Net compiles fine, gcc(g++)
does not.

I have another function that will cause the same compile error.

bool SortCriterion(fooObject * O1, fooObject * O2) {

if (O1->GetFoo() <= O2->GetFoo())
return FALSE;
else
return TRUE;
};

This is then fed to sort as the third arguement. As I understand it the
standard can take a function like the one above as the compare
arguement, why does g++ not like it?

GCC is about a standard compliant as it gets...

It is .Net that is incorrect. There should be an option
to disable Microsoft-extensions. Disable those extensions
to force .NET to conform to the standard.

I don't know what 'TRUE' and 'FALSE' are (neither does the
standard). The C++ boolean keywords are 'true' and 'false'.

I included a working example and the doc for std::sort in my
original post. What is it about that doc that you do not
understand?

The 3rd arg must be a function that returns 'bool'
and takes 2 args of the type stored in the container
(or a ref to same).

If your container stores 'fooObject' instances, your code
would be:

bool SortCriterion(const fooObject& O1, const fooObject& O2)
{
if (O1.GetFoo() <= O2.GetFoo())
return false;
else
return true;
}

Does your container store 'fooObject' instances (fooObject)
or does it store 'fooObject' pointers (fooObject *)?

Provide some example code -and- the actual compiler error
messages generated by that example code.

Regards,
Larry
 
P

Pete Becker

Larry said:
GCC is about a standard compliant as it gets...

It is .Net that is incorrect.

That's a rather strong statement in the absence of actual, complete code
that illustrates the problem. (By the way, G++ has many standard
conformance problems).
 
L

Larry I Smith

Pete said:
That's a rather strong statement in the absence of actual, complete code
that illustrates the problem. (By the way, G++ has many standard
conformance problems).

I'm referring to STL; I should have been more clear.
MS has many non-portable extensions (the old "embrace
and extend" vendor lock in ploy). If trying to write
portable code, these extensions should be disabled
for MS compilers (using the /Za option).

Any GCC extensions should also be disabled (-ansi -pedantic).

The OP appears to be trying to write portable code
(.NET, VC 6, gcc).

I've asked the OP to post actual code and the matching
compiler errors.

Regards,
Larry
 

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

No members online now.

Forum statistics

Threads
474,206
Messages
2,571,069
Members
47,675
Latest member
RollandKna

Latest Threads

Top