How to pass a third argument to compare function?

Discussion in 'C++' started by Lambda, Jun 23, 2008.

  1. Lambda

    Lambda Guest

    I defined a class:

    class inverted_index
    {
    private:
    std::map<std::string, std::vector<size_t> > index;
    public:
    std::vector<size_t> intersect(const std::vector<std::string>&);
    };

    bool compare(const std::string&, const std::string&);

    vector<size_t> inverted_index::intersect(const vector<string>& query)
    {
    sort(query.begin(), query.end(), compare);
    vector<size_t> result = index[query.front()];

    return result;
    }

    bool compare(const string& s1, const string& s2)
    {
    return index[s1].size() < index[s2].size();
    }

    In the intersect function, I want to sort the query by the
    string matching vector size. So I define a compare function fort
    'sort'.

    I think I can't define compare as member function of inverted_index,
    there is a current object as a implicit parameter for member
    functions.
    And the compare will have three parameters. I think it's wrong!

    But if I define compare as a nonmember function with two parameters,
    how can it access the index object. Make it 'friend' is useless here.
    Lambda, Jun 23, 2008
    #1
    1. Advertising

  2. Lambda

    Guest

    On Jun 23, 7:08 pm, Lambda <> wrote:
    > I defined a class:
    >
    > class inverted_index
    > {
    > private:
    >         std::map<std::string, std::vector<size_t> > index;
    > public:
    >         std::vector<size_t> intersect(const std::vector<std::string>&);
    >
    > };
    >
    > bool compare(const std::string&, const std::string&);
    >
    > vector<size_t> inverted_index::intersect(const vector<string>& query)
    > {
    >         sort(query.begin(), query.end(), compare);
    >         vector<size_t> result = index[query.front()];
    >
    >         return result;
    >
    > }
    >
    > bool compare(const string& s1, const string& s2)
    > {
    >         return index[s1].size() < index[s2].size();
    >
    > }
    >
    > In the intersect function, I want to sort the query by the
    > string matching vector size. So I define a compare function fort
    > 'sort'.
    >
    > I think I can't define compare as member function of inverted_index,
    > there is a current object as a implicit parameter for member
    > functions.
    > And the compare will have three parameters. I think it's wrong!
    >
    > But if I define compare as a nonmember function with two parameters,
    > how can it access the index object. Make it 'friend' is useless here.


    a compare functor could help you here. Pls find sample code below

    Class Compare
    {
    public:
    Compare(const int size)
    : size_(size) {} // this could be your required size or so

    bool operator()(const std::string &lhs, const std::string &rhs)
    {
    //your compare here
    }

    private:
    const int size_;
    };

    Thanks,
    Balaji.
    , Jun 23, 2008
    #2
    1. Advertising

  3. Lambda

    dizzy Guest

    Lambda wrote:

    > I defined a class:
    >
    > class inverted_index
    > {
    > private:
    > std::map<std::string, std::vector<size_t> > index;
    > public:
    > std::vector<size_t> intersect(const std::vector<std::string>&);
    > };
    >
    > bool compare(const std::string&, const std::string&);
    >
    > vector<size_t> inverted_index::intersect(const vector<string>& query)
    > {
    > sort(query.begin(), query.end(), compare);
    > vector<size_t> result = index[query.front()];
    >
    > return result;
    > }
    >
    > bool compare(const string& s1, const string& s2)
    > {
    > return index[s1].size() < index[s2].size();
    > }
    >
    > In the intersect function, I want to sort the query by the
    > string matching vector size. So I define a compare function fort
    > 'sort'.
    >
    > I think I can't define compare as member function of inverted_index,
    > there is a current object as a implicit parameter for member
    > functions.
    > And the compare will have three parameters. I think it's wrong!


    Right.

    > But if I define compare as a nonmember function with two parameters,
    > how can it access the index object. Make it 'friend' is useless here.


    That can't work either as you noticed. What you can do is have compare a
    functor (a class type with operator()) that does work in syntax such
    as "compare(string1, string2)" and that has state (has a reference to the
    index it uses for compation). For example

    struct compare
    {
    explicit compare(std::map<std::string, std::vector<size_t> > const& index)
    :index_(index) {}

    bool operator()(std::string const& s1, std::string const& s2) const {
    return index_[s1].size() < index_[s2].size();
    }

    private:
    std::map<std::string, std::vector<size_t> > const& index_;
    };

    Note: to have the code more clear I recommend some (nested?) typedef for
    the "std::map<std::string, std::vector<size_t> >" type and using that.

    In order to use this compare functor you have to construct it giving it a
    reference to the index to use for ordering, like:

    std::sort(begin, end, compare(some-index));

    --
    Dizzy
    dizzy, Jun 23, 2008
    #3
  4. Lambda

    Lambda Guest

    On Jun 23, 10:23 pm, dizzy <> wrote:
    > Lambda wrote:
    > > I defined a class:

    >
    > > class inverted_index
    > > {
    > > private:
    > > std::map<std::string, std::vector<size_t> > index;
    > > public:
    > > std::vector<size_t> intersect(const std::vector<std::string>&);
    > > };

    >
    > > bool compare(const std::string&, const std::string&);

    >
    > > vector<size_t> inverted_index::intersect(const vector<string>& query)
    > > {
    > > sort(query.begin(), query.end(), compare);
    > > vector<size_t> result = index[query.front()];

    >
    > > return result;
    > > }

    >
    > > bool compare(const string& s1, const string& s2)
    > > {
    > > return index[s1].size() < index[s2].size();
    > > }

    >
    > > In the intersect function, I want to sort the query by the
    > > string matching vector size. So I define a compare function fort
    > > 'sort'.

    >
    > > I think I can't define compare as member function of inverted_index,
    > > there is a current object as a implicit parameter for member
    > > functions.
    > > And the compare will have three parameters. I think it's wrong!

    >
    > Right.
    >
    > > But if I define compare as a nonmember function with two parameters,
    > > how can it access the index object. Make it 'friend' is useless here.

    >
    > That can't work either as you noticed. What you can do is have compare a
    > functor (a class type with operator()) that does work in syntax such
    > as "compare(string1, string2)" and that has state (has a reference to the
    > index it uses for compation). For example
    >
    > struct compare
    > {
    >         explicit compare(std::map<std::string, std::vector<size_t> > const& index)
    >         :index_(index) {}
    >
    >         bool operator()(std::string const& s1, std::string const& s2) const {
    >                 return index_[s1].size() < index_[s2].size();
    >         }
    >
    > private:
    >         std::map<std::string, std::vector<size_t> > const& index_;
    >
    > };
    >
    > Note: to have the code more clear I recommend some (nested?) typedef for
    > the "std::map<std::string, std::vector<size_t> >" type and using that.
    >
    > In order to use this compare functor you have to construct it giving it a
    > reference to the index to use for ordering, like:
    >
    > std::sort(begin, end, compare(some-index));
    >
    > --
    > Dizzy


    Thank you for your help!
    This is the first time i use functor.

    Following is my updated code:

    class doc_freq_cmp :
    public std::binary_function<std::string, std::string, bool>
    {
    typedef std::map<std::string, std::vector<size_t> > index_map;
    public:
    explicit doc_freq_cmp(index_map const& index) : index_(index) {}
    bool operator()(std::string const& lhs, std::string const& rhs) const
    {
    return index_[lhs].size() < index_[rhs].size();
    }
    private:
    index_map index_;
    };

    vector<size_t> inverted_index::intersect(const vector<string>& query)
    {
    sort(query.begin(), query.end(), doc_freq_cmp(this->index));
    vector<size_t> result = index[query.front()];

    return result;
    }

    But when i compile, there are errors:
    error C2678: binary '[' : no operator found
    which takes a left-hand operand of type
    'const doc_freq_cmp::index_map' (or there is no acceptable conversion)

    What does it mean? Doesn't std::map support operator[]?

    BTW, what's the difference between a functor inherits from a
    binary predicate and one who does not?
    Lambda, Jun 24, 2008
    #4
    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. Ben Kial
    Replies:
    1
    Views:
    635
    Eric Enright
    Nov 15, 2004
  2. Reckoner
    Replies:
    11
    Views:
    691
    Steven D'Aprano
    Jan 19, 2009
  3. chutsu
    Replies:
    11
    Views:
    789
    jameskuyper
    Jul 30, 2009
  4. Tradeorganizer
    Replies:
    5
    Views:
    162
    Tradeorganizer
    Jan 31, 2007
  5. AikidoGuy
    Replies:
    11
    Views:
    550
    Seebs
    Nov 21, 2011
Loading...

Share This Page