Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   How to pass a third argument to compare function? (http://www.velocityreviews.com/forums/t621807-how-to-pass-a-third-argument-to-compare-function.html)

Lambda 06-23-2008 02:08 PM

How to pass a third argument to compare function?
 
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.

kasthurirangan.balaji@gmail.com 06-23-2008 02:21 PM

Re: How to pass a third argument to compare function?
 
On Jun 23, 7:08*pm, Lambda <stephenh...@gmail.com> 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.

dizzy 06-23-2008 02:23 PM

Re: How to pass a third argument to compare function?
 
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


Lambda 06-24-2008 07:17 AM

Re: How to pass a third argument to compare function?
 
On Jun 23, 10:23*pm, dizzy <di...@roedu.net> 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?


All times are GMT. The time now is 07:38 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.