无法专门化函数模板
这是家庭作业,尽管它已经以不同的方式提交了。
我从 Visual Studio 2008 得到以下内容
error C2893: Failed to specialize function template 'void std::sort(_RanIt,_RanIt,_Pr)'
代码如下
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); }
函数对象定义为
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 { ... } }; ...
这里的解决办法是什么?
[编辑] 抱歉,也许我应该明确继承关系
template <typename C = std::vector<Media *> > class Database : public IDatabase<C>
[/Edit]
[Edit2]
在 Toolbox 的建议(看起来非常合理)之后,我最终得到以下错误消息
error C2664: 'Database<>::sortMedia' : cannot convert parameter 1 from 'sort_by_title' to 'const sort_by &'
main.cpp 仍然相同,但对函子层次结构和源文件进行了一些细微的修改。前向声明等不起作用,因此我不得不将定义放在单独的文件中。
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()); } };
我真的不明白这个,我在这里错过了什么?一些转换操作,还是什么?
[/编辑2]
[编辑3]
我希望最后一次也是最后一次编辑。实际上,我在调试和重写一些代码后得到了这个工作。这就是我最终得到的结果,这是我能做的最好的事情
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);
这似乎有效,无论是在一个单独的项目中(花了今天的大部分时间来搞乱这个),还是在我几天前提交的实际项目中。< br> 非常感谢您的时间和帮助!
[/编辑3]
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]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定这就是导致问题的原因,因为它与专门化
std::sort
无关,但在sortDatabase
中,您不应该传入函子意味着具有多态性。原因是std::sort
按值接受您的函数对象,这意味着它被复制为sort_by
对象,而不是它实际是什么(即您有一个切片)问题)。如果您希望函数对象有一个虚拟
operator()
,函数对象应该保存一个指向多态类的指针,如下所示:然后,
sort_by_impl
可以是您的抽象基特定排序函数对象派生和重写的类。希望有帮助。编辑
根据新的错误消息,如果我不得不猜测,您正在尝试在
sortMedia
内部执行类似的操作:问题在于
my_sort 的类型为
sort_by_title
,它是sort_by_impl
的派生形式 - 不是类型的sort_by
。这意味着您实际上希望将my_sort
传递为sort_by
对象中的sbp
指针,这是您将使用的实际函数对象。为了说明这一点:顺便说一句,代码不是异常安全的;考虑用引用计数智能指针替换 sbp。或者更简单,只需在堆栈上声明
sort_by_title
并传入其地址即可。只是要小心,不要让它在使用之前被破坏。 :)希望有帮助。让我知道结果如何!
I'm not sure this is what's causing the problem, as it has nothing to do with specializing
std::sort
, but insortDatabase
you shouldn't be passing in a functor that's meant to behave polymorphically. The reason is thatstd::sort
accepts your function object by value, which means it gets copied as asort_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: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
:The problem is that
my_sort
is of typesort_by_title
, which is a derived form ofsort_by_impl
- not of typesort_by
. That means you actually want to passmy_sort
to be thesbp
pointer in asort_by
object, which is the actual function object you'll use. To illustrate: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!