472,133 Members | 1,167 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,133 software developers and data experts.

Need help on std::sort comparison function


Good afternoon,
I need some advice on the following:

I've got a class that has a member
std::vector<CStringm_vFileName and a member CString m_path;
The vector contains a bunch of filenames with no path included
(no C:\...) eg: my_file2.jpg, my_file1.bmp, etc...
and m_path stores the path, eg: C:\folder1

I want to sort this vector according to different criterion, such as
filename(asc, desc), date(asc, desc), size(asc, desc).

To sort the vector by filename I use this comparison function:
bool sortVectorByNameUp(CString s1, CString s2)
{ return (s1.CompareNoCase(s2) <= 0)? true : false; }

the call is std::sort(m_vFileName.begin(), m_vFileName.end(),
sortVectorByNameUp);

To sort this vector by date I need to obtain last access time for every
file, and for that, I need to read m_path :(
I can't pass m_path as a parameter because (I think), sortVectorByNameUp
must be a binary function.

If I make this function a member of my class
eg: bool Cteste8View::sortVectorByNameUp(CString s1, CString s2)

I get compilation errors:
..\teste8View.cpp(478) : error C3867: 'Cteste8View::sortVectorByNameUp':
function call missing argument list; use
'&Cteste8View::sortVectorByNameUp' to create a pointer to member
..\teste8View.cpp(478) : error C2780: 'void std::sort(_RanIt,_RanIt)' :
expects 2 arguments - 3 provided
C:\Program Files\Microsoft Visual Studio 8\VC\include\algorithm
(2751) : see declaration of 'std::sort'

I've tried making the call like this:
std::sort(m_vFileName.begin(), m_vFileName.end(),
&Cteste8View::sortVectorByNameUp);
but it doesn't work either

Is there a way to have access to m_path inside the comparison function,
besides using a global variable as intermediate?
And what is the best way to get size and last access time from a file?

Thanks a lot in advance
--
fade
email: fade(*AT*)forward(*dot*)to
Dec 21 '06 #1
5 3743
In article <Xn********************@194.65.14.158>,
fade <do****************@mail.comwrote:
Good afternoon,
I need some advice on the following:

I've got a class that has a member
std::vector<CStringm_vFileName and a member CString m_path;
The vector contains a bunch of filenames with no path included
(no C:\...) eg: my_file2.jpg, my_file1.bmp, etc...
and m_path stores the path, eg: C:\folder1

I want to sort this vector according to different criterion, such as
filename(asc, desc), date(asc, desc), size(asc, desc).

To sort the vector by filename I use this comparison function:
bool sortVectorByNameUp(CString s1, CString s2)
{ return (s1.CompareNoCase(s2) <= 0)? true : false; }

the call is std::sort(m_vFileName.begin(), m_vFileName.end(),
sortVectorByNameUp);

To sort this vector by date I need to obtain last access time for every
file, and for that, I need to read m_path :(
I can't pass m_path as a parameter because (I think), sortVectorByNameUp
must be a binary function.

If I make this function a member of my class
eg: bool Cteste8View::sortVectorByNameUp(CString s1, CString s2)

I get compilation errors:
.\teste8View.cpp(478) : error C3867: 'Cteste8View::sortVectorByNameUp':
function call missing argument list; use
'&Cteste8View::sortVectorByNameUp' to create a pointer to member
.\teste8View.cpp(478) : error C2780: 'void std::sort(_RanIt,_RanIt)' :
expects 2 arguments - 3 provided
C:\Program Files\Microsoft Visual Studio 8\VC\include\algorithm
(2751) : see declaration of 'std::sort'

I've tried making the call like this:
std::sort(m_vFileName.begin(), m_vFileName.end(),
&Cteste8View::sortVectorByNameUp);
but it doesn't work either

Is there a way to have access to m_path inside the comparison function,
besides using a global variable as intermediate?
And what is the best way to get size and last access time from a file?

Thanks a lot in advance
struct SortVectorByDateUp : binary_function< CString, CString, bool >
{
const CString path;
SortVectorByDateUp( const CString& path_ ): path( path_ ) { }
bool operator()( const CString& left, const CString& right ) const
{
// do whatever you need to do here
}
};

// in body of member function

sort( m_vFileName.begin(), m_vFileName.end(),
SortVectorByDateUp( m_path ) );
Dec 21 '06 #2

fade wrote:
Good afternoon,
I need some advice on the following:

I've got a class that has a member
std::vector<CStringm_vFileName and a member CString m_path;
The vector contains a bunch of filenames with no path included
(no C:\...) eg: my_file2.jpg, my_file1.bmp, etc...
and m_path stores the path, eg: C:\folder1

I want to sort this vector according to different criterion, such as
filename(asc, desc), date(asc, desc), size(asc, desc).

To sort the vector by filename I use this comparison function:
bool sortVectorByNameUp(CString s1, CString s2)
{ return (s1.CompareNoCase(s2) <= 0)? true : false; }
That doesn't sort the vector by filename, it sorts copies which
can/might be modified, not to mention the waste of invoking additional
ctors and d~tors. That statement might sound a little strange for
someone that is doing MFC, or whatever proprietary language you are
using, but thats absolutely fundamental in C++. Comparison parameters
must be const references. Doing otherwise is shooting yourself in the
foot.
Try:
bool sortVectorByNameUp(const CString& s1, const CString& s2)
{
// ...
}

You should both consider and study associative containers (like
std::set or std::map). These sort at insertion and can simply rely on
an operator< overload to order the container. If you decide to go that
route, you'll find out how dangerous it is not to use const references
in this case.
>
the call is std::sort(m_vFileName.begin(), m_vFileName.end(),
sortVectorByNameUp);

To sort this vector by date I need to obtain last access time for every
file, and for that, I need to read m_path :(
I can't pass m_path as a parameter because (I think), sortVectorByNameUp
must be a binary function.

If I make this function a member of my class
eg: bool Cteste8View::sortVectorByNameUp(CString s1, CString s2)
no, no. Assuming that the vector in question is part of the CTeste8View
class, you don't provide a member function that sorts the vector member
within by passing its elements to an interface of the containing class.
Thats not logical and will obviously fail in an algorithm.
Your vector should be storing Elements of some structure or class, that
class/struct is where the op< or comparator should act upon. One does
not ask an apple tree to compare apples. Trees compare trees and apples
compare apples.
>
I get compilation errors:
.\teste8View.cpp(478) : error C3867: 'Cteste8View::sortVectorByNameUp':
function call missing argument list; use
'&Cteste8View::sortVectorByNameUp' to create a pointer to member
.\teste8View.cpp(478) : error C2780: 'void std::sort(_RanIt,_RanIt)' :
expects 2 arguments - 3 provided
The error is expected. sort is being asked to act on a Cteste8View
object and yet the iterators are iterating through CStrings.
C:\Program Files\Microsoft Visual Studio 8\VC\include\algorithm
(2751) : see declaration of 'std::sort'

I've tried making the call like this:
std::sort(m_vFileName.begin(), m_vFileName.end(),
&Cteste8View::sortVectorByNameUp);
but it doesn't work either

Is there a way to have access to m_path inside the comparison function,
besides using a global variable as intermediate?
And what is the best way to get size and last access time from a file?

Thanks a lot in advance
--
fade
email: fade(*AT*)forward(*dot*)to
Dec 21 '06 #3

fade wrote:
Good afternoon,
I need some advice on the following:

I've got a class that has a member
std::vector<CStringm_vFileName and a member CString m_path;
The vector contains a bunch of filenames with no path included
(no C:\...) eg: my_file2.jpg, my_file1.bmp, etc...
and m_path stores the path, eg: C:\folder1

I want to sort this vector according to different criterion, such as
filename(asc, desc), date(asc, desc), size(asc, desc).

To sort this vector by date I need to obtain last access time for every
file, and for that, I need to read m_path :(
I can't pass m_path as a parameter because (I think), sortVectorByNameUp
must be a binary function.
Make it a functor, an object that has an operator() that takes two
params, or make it a member function and use a binder or boost::bind (I
recommend the later) to tie it to the instance of the object in
question.
I've tried making the call like this:
std::sort(m_vFileName.begin(), m_vFileName.end(),
&Cteste8View::sortVectorByNameUp);
Cteste8View::sortByNameUp()
{
std::sort(begin(), end(), boost::bind(&CTeste8View::sortVByName,
this, _1, _2));
}

Dec 21 '06 #4
"Salt_Peter" <pj*****@yahoo.comwrote:
fade wrote:

I've got a class that has a member
std::vector<CStringm_vFileName and a member CString m_path;
The vector contains a bunch of filenames with no path included
(no C:\...) eg: my_file2.jpg, my_file1.bmp, etc...
and m_path stores the path, eg: C:\folder1

I want to sort this vector according to different criterion, such as
filename(asc, desc), date(asc, desc), size(asc, desc).

To sort the vector by filename I use this comparison function:
bool sortVectorByNameUp(CString s1, CString s2)
{ return (s1.CompareNoCase(s2) <= 0)? true : false; }

That doesn't sort the vector by filename, it sorts copies which
can/might be modified, not to mention the waste of invoking additional
ctors and d~tors. That statement might sound a little strange for
someone that is doing MFC, or whatever proprietary language you are
using, but thats absolutely fundamental in C++. Comparison parameters
must be const references. Doing otherwise is shooting yourself in the
foot.
Your assertion is incorrect. The only thing that the standard requires
of the predicate is that it satisfy the standard mathematical definition
of a strict weak ordering.

The additional c_tors and d_tors that are invoked, might, or might not,
prove to be a performance hit, one can't know without testing.

That said, parameters of 'const T&' and 'T' are logically equivelent and
the former is highly unlikely to be slower than the latter, and for
non-builtin types, is likely to be faster. So I do agree that the OP
should try using 'const T&' instead.
Dec 21 '06 #5
struct SortVectorByDateUp : binary_function< CString, CString, bool >
{
const CString path;
SortVectorByDateUp( const CString& path_ ): path( path_ ) { }
bool operator()( const CString& left, const CString& right ) const
{
// do whatever you need to do here
}
};

// in body of member function

sort( m_vFileName.begin(), m_vFileName.end(),
SortVectorByDateUp( m_path ) );
Thanks a lot Daniel, Peter and Noah.
Merry Xmas to all.

--
fade
email: fade(*AT*)forward(*dot*)to
Dec 23 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by lok | last post: by
6 posts views Thread by alexhong2001 | last post: by
7 posts views Thread by Ireneusz SZCZESNIAK | last post: by
8 posts views Thread by Manfred | last post: by
11 posts views Thread by Jeff Schwab | last post: by

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.