Need help on std::sort comparison function

Discussion in 'C++' started by fade, Dec 21, 2006.

  1. fade

    fade Guest

    Good afternoon,
    I need some advice on the following:

    I've got a class that has a member
    std::vector<CString> m_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
     
    fade, Dec 21, 2006
    #1
    1. Advertising

  2. fade

    Daniel T. Guest

    In article <Xns98A0BEAB42EEAfadept@194.65.14.158>,
    fade <> wrote:

    > Good afternoon,
    > I need some advice on the following:
    >
    > I've got a class that has a member
    > std::vector<CString> m_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 ) );
     
    Daniel T., Dec 21, 2006
    #2
    1. Advertising

  3. fade

    Salt_Peter Guest

    fade wrote:
    > Good afternoon,
    > I need some advice on the following:
    >
    > I've got a class that has a member
    > std::vector<CString> m_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
     
    Salt_Peter, Dec 21, 2006
    #3
  4. fade

    Noah Roberts Guest

    fade wrote:
    > Good afternoon,
    > I need some advice on the following:
    >
    > I've got a class that has a member
    > std::vector<CString> m_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));
    }
     
    Noah Roberts, Dec 21, 2006
    #4
  5. fade

    Daniel T. Guest

    "Salt_Peter" <> wrote:
    > fade wrote:
    > >
    > > I've got a class that has a member
    > > std::vector<CString> m_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.
     
    Daniel T., Dec 21, 2006
    #5
  6. fade

    fade Guest


    > 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
     
    fade, Dec 23, 2006
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Rasmussen

    Comparison function to sort()

    David Rasmussen, Oct 21, 2005, in forum: C++
    Replies:
    11
    Views:
    567
    Rolf Magnus
    Oct 22, 2005
  2. Replies:
    1
    Views:
    513
    Marcus Kwok
    Apr 6, 2007
  3. Stephen Horne
    Replies:
    3
    Views:
    647
    Stephen Horne
    Aug 5, 2009
  4. Navin
    Replies:
    1
    Views:
    770
    Ken Schaefer
    Sep 9, 2003
  5. GIMME
    Replies:
    5
    Views:
    202
    Thomas 'PointedEars' Lahn
    Jul 26, 2004
Loading...

Share This Page