operator< for algorithms

Discussion in 'C++' started by Hicham Mouline, Apr 2, 2009.

  1. Hello,

    namespace NS1 { namespace NS2 {

    template <typename T1, typename T2>
    class C {
    public:
    typedef T1::xType xType;
    typedef T1::yType yType;
    ....
    private:
    typedef std::pair< xType, yType> EntryType;
    boost::array< EntryType , size > ContainerType;
    ....
    };
    ....
    }}

    I need to use std::lower_bound and sorting algorithms on my ContainerType.

    Where (which namespace) and how can I define the operator< comparing 2
    EntryType
    for the std:: algorithms to use that operator?

    Note I use these std::algorithms only in member functions of the C template.
    So I wish to define the operator< in a way that is specific and visible only
    to C template.

    best regards,
     
    Hicham Mouline, Apr 2, 2009
    #1
    1. Advertising

  2. Hicham Mouline wrote:
    > namespace NS1 { namespace NS2 {
    >
    > template <typename T1, typename T2>
    > class C {
    > public:
    > typedef T1::xType xType;
    > typedef T1::yType yType;
    > ...
    > private:
    > typedef std::pair< xType, yType> EntryType;
    > boost::array< EntryType , size > ContainerType;
    > ....
    > };
    > ...
    > }}
    >
    > I need to use std::lower_bound and sorting algorithms on my ContainerType.
    >
    > Where (which namespace) and how can I define the operator< comparing 2
    > EntryType
    > for the std:: algorithms to use that operator?


    Anywhere appropriate. Any namespace/class where your compiler is
    capable of finding it.

    > Note I use these std::algorithms only in member functions of the C template.
    > So I wish to define the operator< in a way that is specific and visible only
    > to C template.


    Have you tried defining it as a static member of the C template?

    Post the rest of your code, with only the operator< missing, and we can
    probably figure it out. I am just too lazy to provide all the necessary
    driver code for what you've described, I consider it your job if you
    want my help. Sorry, such a PITA I am.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 2, 2009
    #2
    1. Advertising

  3. "Victor Bazarov" <> wrote in message
    news:gr2bjd$st4$...
    > Hicham Mouline wrote:
    >> namespace NS1 { namespace NS2 {
    >>
    >> template <typename T1, typename T2>
    >> class C {
    >> public:
    >> typedef T1::xType xType;
    >> typedef T1::yType yType;
    >> ...
    >> private:
    >> typedef std::pair< xType, yType> EntryType;
    >> boost::array< EntryType , size > ContainerType;
    >> ....
    >> };
    >> ...
    >> }}
    >>
    >> I need to use std::lower_bound and sorting algorithms on my
    >> ContainerType.
    >>
    >> Where (which namespace) and how can I define the operator< comparing 2
    >> EntryType
    >> for the std:: algorithms to use that operator?

    >
    > Anywhere appropriate. Any namespace/class where your compiler is capable
    > of finding it.
    >
    >> Note I use these std::algorithms only in member functions of the C
    >> template.
    >> So I wish to define the operator< in a way that is specific and visible
    >> only to C template.

    >
    > Have you tried defining it as a static member of the C template?
    >
    > Post the rest of your code, with only the operator< missing, and we can
    > probably figure it out. I am just too lazy to provide all the necessary
    > driver code for what you've described, I consider it your job if you want
    > my help. Sorry, such a PITA I am.
    >
    > V

    Not at all. Thank you for your contrib!

    I put the code here
    http://codepad.org/Gwfm36GL

    It fails to compile under g++4
    "operator< needs to be must be either a non-static member function or a
    non-member function"

    if it is member non-static, it is interpreted as applying to C<T1,T2> not to
    EntryType

    As EntryType is private, I don't know how to define outside of C<T1,T2>

    rds,
     
    Hicham Mouline, Apr 2, 2009
    #3
  4. Hicham Mouline wrote:
    > "Victor Bazarov" <> wrote in message
    > news:gr2bjd$st4$...
    >> Hicham Mouline wrote:
    >>> namespace NS1 { namespace NS2 {
    >>>
    >>> template <typename T1, typename T2>
    >>> class C {
    >>> public:
    >>> typedef T1::xType xType;
    >>> typedef T1::yType yType;
    >>> ...
    >>> private:
    >>> typedef std::pair< xType, yType> EntryType;
    >>> boost::array< EntryType , size > ContainerType;
    >>> ....
    >>> };
    >>> ...
    >>> }}
    >>>
    >>> I need to use std::lower_bound and sorting algorithms on my
    >>> ContainerType.
    >>>
    >>> Where (which namespace) and how can I define the operator< comparing 2
    >>> EntryType
    >>> for the std:: algorithms to use that operator?

    >> Anywhere appropriate. Any namespace/class where your compiler is capable
    >> of finding it.
    >>
    >>> Note I use these std::algorithms only in member functions of the C
    >>> template.
    >>> So I wish to define the operator< in a way that is specific and visible
    >>> only to C template.

    >> Have you tried defining it as a static member of the C template?
    >>
    >> Post the rest of your code, with only the operator< missing, and we can
    >> probably figure it out. I am just too lazy to provide all the necessary
    >> driver code for what you've described, I consider it your job if you want
    >> my help. Sorry, such a PITA I am.
    >>
    >> V

    > Not at all. Thank you for your contrib!
    >
    > I put the code here
    > http://codepad.org/Gwfm36GL
    >
    > It fails to compile under g++4
    > "operator< needs to be must be either a non-static member function or a
    > non-member function"
    >
    > if it is member non-static, it is interpreted as applying to C<T1,T2> not to
    > EntryType
    >
    > As EntryType is private, I don't know how to define outside of C<T1,T2>


    I managed to make your code from the 'codepad.org' to compile when I
    removed the operator< definition from the 'C' template (it wasn't the
    brightest suggestion, I guess) and put it right after the 'C' as this:

    template<class T, class U>
    bool operator<(const typename C<T,U>::EntryType& lhs,
    const typename C<T,U>::EntryType& rhs)
    {
    return true;
    }

    I am not sure how to try it with Comeau online.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 2, 2009
    #4
  5. "Victor Bazarov" <> wrote in message
    news:gr2jto$g24$...
    > Hicham Mouline wrote:
    >> "Victor Bazarov" <> wrote in message
    >> news:gr2bjd$st4$...
    >>> Hicham Mouline wrote:
    >>>> namespace NS1 { namespace NS2 {
    >>>>
    >>>> template <typename T1, typename T2>
    >>>> class C {
    >>>> public:
    >>>> typedef T1::xType xType;
    >>>> typedef T1::yType yType;
    >>>> ...
    >>>> private:
    >>>> typedef std::pair< xType, yType> EntryType;
    >>>> boost::array< EntryType , size > ContainerType;
    >>>> ....
    >>>> };
    >>>> ...
    >>>> }}
    >>>>
    >>>> I need to use std::lower_bound and sorting algorithms on my
    >>>> ContainerType.
    >>>>
    >>>> Where (which namespace) and how can I define the operator< comparing 2
    >>>> EntryType
    >>>> for the std:: algorithms to use that operator?
    >>> Anywhere appropriate. Any namespace/class where your compiler is
    >>> capable of finding it.
    >>>
    >>>> Note I use these std::algorithms only in member functions of the C
    >>>> template.
    >>>> So I wish to define the operator< in a way that is specific and visible
    >>>> only to C template.
    >>> Have you tried defining it as a static member of the C template?
    >>>
    >>> Post the rest of your code, with only the operator< missing, and we can
    >>> probably figure it out. I am just too lazy to provide all the necessary
    >>> driver code for what you've described, I consider it your job if you
    >>> want my help. Sorry, such a PITA I am.
    >>>
    >>> V

    >> Not at all. Thank you for your contrib!
    >>
    >> I put the code here
    >> http://codepad.org/Gwfm36GL
    >>
    >> It fails to compile under g++4
    >> "operator< needs to be must be either a non-static member function or a
    >> non-member function"
    >>
    >> if it is member non-static, it is interpreted as applying to C<T1,T2> not
    >> to EntryType
    >>
    >> As EntryType is private, I don't know how to define outside of C<T1,T2>

    >
    > I managed to make your code from the 'codepad.org' to compile when I
    > removed the operator< definition from the 'C' template (it wasn't the
    > brightest suggestion, I guess) and put it right after the 'C' as this:
    >
    > template<class T, class U>
    > bool operator<(const typename C<T,U>::EntryType& lhs,
    > const typename C<T,U>::EntryType& rhs)
    > {
    > return true;
    > }

    It is strange that this compiles.
    EntryType is private, why does operator< outside manage to access it?

    Let me now see if that operator< is really used by lower_bound,

    rds,
     
    Hicham Mouline, Apr 2, 2009
    #5
  6. Hicham Mouline wrote:
    > "Victor Bazarov" <> wrote in message
    > news:gr2jto$g24$...
    >> Hicham Mouline wrote:
    >>> "Victor Bazarov" <> wrote in message
    >>> news:gr2bjd$st4$...
    >>>> Hicham Mouline wrote:
    >>>>> namespace NS1 { namespace NS2 {
    >>>>>
    >>>>> template <typename T1, typename T2>
    >>>>> class C {
    >>>>> public:
    >>>>> typedef T1::xType xType;
    >>>>> typedef T1::yType yType;
    >>>>> ...
    >>>>> private:
    >>>>> typedef std::pair< xType, yType> EntryType;
    >>>>> boost::array< EntryType , size > ContainerType;
    >>>>> ....
    >>>>> };
    >>>>> ...
    >>>>> }}
    >>>>>
    >>>>> I need to use std::lower_bound and sorting algorithms on my
    >>>>> ContainerType.
    >>>>>
    >>>>> Where (which namespace) and how can I define the operator< comparing 2
    >>>>> EntryType
    >>>>> for the std:: algorithms to use that operator?
    >>>> Anywhere appropriate. Any namespace/class where your compiler is
    >>>> capable of finding it.
    >>>>
    >>>>> Note I use these std::algorithms only in member functions of the C
    >>>>> template.
    >>>>> So I wish to define the operator< in a way that is specific and visible
    >>>>> only to C template.
    >>>> Have you tried defining it as a static member of the C template?
    >>>>
    >>>> Post the rest of your code, with only the operator< missing, and we can
    >>>> probably figure it out. I am just too lazy to provide all the necessary
    >>>> driver code for what you've described, I consider it your job if you
    >>>> want my help. Sorry, such a PITA I am.
    >>>>
    >>>> V
    >>> Not at all. Thank you for your contrib!
    >>>
    >>> I put the code here
    >>> http://codepad.org/Gwfm36GL
    >>>
    >>> It fails to compile under g++4
    >>> "operator< needs to be must be either a non-static member function or a
    >>> non-member function"
    >>>
    >>> if it is member non-static, it is interpreted as applying to C<T1,T2> not
    >>> to EntryType
    >>>
    >>> As EntryType is private, I don't know how to define outside of C<T1,T2>

    >> I managed to make your code from the 'codepad.org' to compile when I
    >> removed the operator< definition from the 'C' template (it wasn't the
    >> brightest suggestion, I guess) and put it right after the 'C' as this:
    >>
    >> template<class T, class U>
    >> bool operator<(const typename C<T,U>::EntryType& lhs,
    >> const typename C<T,U>::EntryType& rhs)
    >> {
    >> return true;
    >> }

    > It is strange that this compiles.
    > EntryType is private, why does operator< outside manage to access it?


    It is quite possible that since all instantiations of that operator are
    made from inside a member function of 'C', where access to 'EntryType'
    is granted, the compiler considers it an implicit permission...

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 2, 2009
    #6
  7. "Victor Bazarov" <> wrote in message
    news:gr2kp5$i4s$...
    >>> template<class T, class U>
    >>> bool operator<(const typename C<T,U>::EntryType& lhs,
    >>> const typename C<T,U>::EntryType& rhs)
    >>> {
    >>> return true;
    >>> }

    >> It is strange that this compiles.
    >> EntryType is private, why does operator< outside manage to access it?

    >
    > It is quite possible that since all instantiations of that operator are
    > made from inside a member function of 'C', where access to 'EntryType' is
    > granted, the compiler considers it an implicit permission...

    It doesn't seem to work

    template<class T, class U>
    bool operator<(const typename C<T,U>::EntryType& lhs,
    const typename C<T,U>::EntryType& rhs)
    {
    std::cout<< "called" <<std::endl;
    return true;
    }

    never prints anything

    I just realized c++03 defines operators< for std::pair<> in std.

    Maybe I need to override those

    rds,
     
    Hicham Mouline, Apr 2, 2009
    #7
  8. "Hicham Mouline" <> wrote in message
    news:49d4d773$0$90275$...
    > It doesn't seem to work
    >
    > template<class T, class U>
    > bool operator<(const typename C<T,U>::EntryType& lhs,
    > const typename C<T,U>::EntryType& rhs)
    > {
    > std::cout<< "called" <<std::endl;
    > return true;
    > }
    >
    > never prints anything
    >
    > I just realized c++03 defines operators< for std::pair<> in std.
    >
    > Maybe I need to override those
    >
    > rds,


    still doesn't wor, strange
    http://codepad.org/h9uFoI1I

    rds,
     
    Hicham Mouline, Apr 2, 2009
    #8
  9. Hicham Mouline wrote:
    > "Hicham Mouline" <> wrote in message
    > news:49d4d773$0$90275$...
    >> It doesn't seem to work
    >>
    >> template<class T, class U>
    >> bool operator<(const typename C<T,U>::EntryType& lhs,
    >> const typename C<T,U>::EntryType& rhs)
    >> {
    >> std::cout<< "called" <<std::endl;
    >> return true;
    >> }
    >>
    >> never prints anything
    >>
    >> I just realized c++03 defines operators< for std::pair<> in std.
    >>
    >> Maybe I need to override those
    >>
    >> rds,

    >
    > still doesn't wor, strange
    > http://codepad.org/h9uFoI1I


    Hm...

    I tried redefining your type 'EntryType' as derived from 'std::pair',
    and it didn't help either.

    I don't know. Apparently the compiler is unable to resolve it (or
    instantiate the template) and if falls back on what it can do, the
    operator < for std::pair...

    I think you should resort to a named function/functor:

    template<class T, class U>
    bool op_less(const typename NS1::NS2::C<T,U>::EntryType& lhs,
    const typename NS1::NS2::C<T,U>::EntryType& rhs)
    {
    std::cout<< "called" <<std::endl;
    return true;
    }

    ....
    template<typename T1, typename T2>
    void C<T1, T2>::FindX(xType x) const
    {
    std::cout<< "inside Find"<<std::endl;
    if ( op_less<T1,T2>(mContainer[0], mContainer[1]) )
    {
    std::cout<<" 0 < 1 "<<std::endl;
    }
    if ( op_less<T1,T2>(mContainer[1], mContainer[0]) )
    {
    std::cout<<" 1 < 0 "<<std::endl;
    }
    }


    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 2, 2009
    #9
  10. Hicham Mouline

    James Kanze Guest

    On Apr 2, 2:17 pm, "Hicham Mouline" <> wrote:

    > namespace NS1 { namespace NS2 {


    > template <typename T1, typename T2>
    > class C {
    > public:
    > typedef T1::xType xType;
    > typedef T1::yType yType;


    You are, presumably, using an older compiler. The above
    shouldn't compile (and won't with most newer compilers); you
    need an additional typename.

    > ...
    > private:
    > typedef std::pair< xType, yType> EntryType;
    > boost::array< EntryType , size > ContainerType;
    > ....


    > };
    > ...
    > }}


    > I need to use std::lower_bound and sorting algorithms on my
    > ContainerType.


    That could be tricky if either xType or yType don't support
    comparison. And if they both support <, then your EntryType
    already has an operator<, which you don't want to change (since
    that would confuse any reader). And if EntryType supports <,
    then boost::array should as well. (I've not verified the
    latter, but as far as I know, boost::array adheres to the
    requirements of a container in the standard.)

    > Where (which namespace) and how can I define the operator<
    > comparing 2 EntryType for the std:: algorithms to use that
    > operator?


    > Note I use these std::algorithms only in member functions of
    > the C template. So I wish to define the operator< in a way
    > that is specific and visible only to C template.


    That's a tricky one. The correct answer is: in the namespace
    where one of the actual types was defined, i.e. where the T1 of
    the instantiation was defined. Except that, as mentionned, you
    can't define an operator< for EntryType or ContainerType, since
    the standard already defines one.

    If the standard operator isn't appropriate, then There are two
    simple solutions:

    -- Drop std::pair. Using it is probably an error anyway---do
    the two components really have a semantic of "first" and
    "second"? (There are cases where they do, but in those
    cases, the standard operator is appropriate.) Just define a
    nested class (or simply a struct) with the two types, and
    the operator< defined as you want.

    -- Don't use <. All of the functions involving order (sort,
    lower_bound, etc.) have a overload taking an additional
    argument specifying the ordering function. So you provide a
    nested class (fuctional object) which defines the ordering
    you want, and pass an instance of it to the function each
    time.

    --
    James Kanze (GABI Software) email:
    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
     
    James Kanze, Apr 3, 2009
    #10
  11. "James Kanze" <> wrote in message
    news:...
    On Apr 2, 2:17 pm, "Hicham Mouline" <> wrote:
    -- Don't use <. All of the functions involving order (sort,
    lower_bound, etc.) have a overload taking an additional
    argument specifying the ordering function. So you provide a
    nested class (fuctional object) which defines the ordering
    you want, and pass an instance of it to the function each
    time.


    Thanks. I went with the 2nd solution

    inner class
    // EntryType comparison predicate
    struct EntryTypeLess : public std::binary_function<EntryType, EntryType,
    bool> {
    bool operator() ( const EntryType& lhs, const EntryType& rhs ) const
    {
    return lhs.first < rhs.first;
    }

    which I then use as the Cmp in lower_bound, and I use once explicitly.

    best regards,
     
    Hicham Mouline, Apr 3, 2009
    #11
    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. Andreas
    Replies:
    0
    Views:
    521
    Andreas
    Dec 2, 2003
  2. abhinav

    encryption algorithms

    abhinav, Dec 26, 2004, in forum: VHDL
    Replies:
    2
    Views:
    660
  3. Melanie Nasic
    Replies:
    19
    Views:
    3,073
    Thomas Rudloff
    Jan 1, 2006
  4. Soenke
    Replies:
    0
    Views:
    577
    Soenke
    Dec 28, 2005
  5. Stephen Howe
    Replies:
    1
    Views:
    275
    Victor Bazarov
    Nov 15, 2010
Loading...

Share This Page