This is homework, although it's already submitted with a different approach.
I'm getting the following from Visual Studio 2008
error C2893: Failed to specialize function template 'void std::sort(_RanIt,_RanIt,_Pr)'
The code is as follows
main.cpp Database<> db; db.loadDatabase(); db.sortDatabase(sort_by_title()); Database.cpp void Database<C>::sortDatabase(const sort_by &s) { std::sort(db_.begin(), db_.end(), s); }
And the function objects are defined as
struct sort_by : public std::binary_function<const Media *, const Media *, bool> { virtual bool operator()(const Media *l, const Media *r) const = 0; }; struct sort_by_title : public sort_by { bool operator()(const Media *l, const Media *r) const { ... } }; ...
What's the cure here?
[Edit] Sorry, maybe I should have made the inheritance clear
template <typename C = std::vector<Media *> > class Database : public IDatabase<C>
[/Edit]
[Edit2]
After the suggestion from Toolbox (which seemed very reasonable) I ended up with the following error message
error C2664: 'Database<>::sortMedia' : cannot convert parameter 1 from 'sort_by_title' to 'const sort_by &'
main.cpp is still the same, but with some slight modifications to the functor hierarchy and source files. Forward declarations and such did not work so I had to put the definitions in separate files.
Search.h struct sort_by_impl { virtual bool operator()(const Media *l, const Media *r) const = 0; }; struct sort_by : public std::binary_function<const Media *, const Media *, bool> { sort_by_impl *sbp; bool operator()(const Media *l, const Media *r) const { return (*sbp)(l, r); } }; IDatabase.h struct sort_by_title : public sort_by_impl { bool operator()(const Media *l, const Media *r) const { return (l->getTitle() < r->getTitle()); } };
I'm really not grokking this, what am I missing here? Some conversion operation, or what?
[/Edit2]
[Edit3]
Last and final edit, I hope. I actually got this working after debugging and rewriting some of the code. This is what I ended up with, and it's the best I could do
class sort_by : public std::binary_function<const Media *, const Media *, bool> { public: sort_by(sort_by_impl *sbp) : sbp_(sbp) {}; bool operator()(const Media *l, const Media *r) const { return (*sbp_)(l, r); } private: sort_by_impl *sbp_; }; main.cpp db.sortDatabase(&sort_by_title()); Database.cpp void Database<C>::sortDatabase(const sort_by &s) { std::sort(db_.begin(), db_.end(), s);
This seems to work, both in a separate project (spending the better part of this day messing with this) and in my actual project which I submitted some days ago.
Thank you very much for your time and help!
[/Edit3]
To instantiate a template function explicitly, follow the template keyword by a declaration (not definition) for the function, with the function identifier followed by the template arguments. template float twice<float>( float original ); Template arguments may be omitted when the compiler can infer them.
Defining a Function TemplateA function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.
Function templates are similar to class templates but define a family of functions. With function templates, you can specify a set of functions that are based on the same code but act on different types or classes.
I'm not sure this is what's causing the problem, as it has nothing to do with specializing std::sort
, but in sortDatabase
you shouldn't be passing in a functor that's meant to behave polymorphically. The reason is that std::sort
accepts your function object by value, which means it gets copied as a sort_by
object, not whatever it actually is (i.e. you have a slicing problem).
If you want the function object to have a virtual operator()
, the function object should hold a pointer to the polymorphic class like so:
struct sort_by : public std::binary_function<const Media*, const Media*, bool> {
bool operator()(const Media *l, const Media *r) const
{
return (*p_impl)(l, r);
}
sort_by_impl* p_impl;
};
Then, sort_by_impl
can be your abstract base class from which specific sorting function objects derive and override. Hope that helps.
EDIT
Based on the new error message, if I had to guess, you're trying to do something like this inside sortMedia
:
Database<std::vector<Media*> > db; // initialized elsewhere...
sort_by_title my_sort;
db.sortDatabase(my_sort);
The problem is that my_sort
is of type sort_by_title
, which is a derived form of sort_by_impl
- not of type sort_by
. That means you actually want to pass my_sort
to be the sbp
pointer in a sort_by
object, which is the actual function object you'll use. To illustrate:
Database<std::vector<Media*> > db; // initialized elsewhere...
sort_by my_sort_fn;
my_sort_fn.sbp = new sort_by_title;
db.sortDatabase(my_sort_fn);
delete my_sort_fn.sbp;
The code isn't exception safe, by the way; consider replacing sbp with a reference-counting smart pointer. Or even easier, just declare the sort_by_title
on the stack and pass in its address. Just be careful not to let it be destroyed before it's used. :)
Hopefully that helps. Let me know how it turns out!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With