无法专门化函数模板

发布于 2024-10-10 22:46:34 字数 2368 浏览 9 评论 0原文

这是家庭作业,尽管它已经以不同的方式提交了。

我从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

预谋 2024-10-17 22:46:34

我不确定这就是导致问题的原因,因为它与专门化 std::sort 无关,但在 sortDatabase 中,您不应该传入函子意味着具有多态性。原因是 std::sort 按值接受您的函数对象,这意味着它被复制为 sort_by 对象,而不是它实际是什么(即您有一个切片)问题)。

如果您希望函数对象有一个虚拟operator(),函数对象应该保存一个指向多态类的指针,如下所示:

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;
};

然后,sort_by_impl可以是您的抽象基特定排序函数对象派生和重写的类。希望有帮助。

编辑

根据新的错误消息,如果我不得不猜测,您正在尝试在sortMedia内部执行类似的操作:

Database<std::vector<Media*> > db; // initialized elsewhere...

sort_by_title my_sort;
db.sortDatabase(my_sort);

问题在于my_sort 的类型为 sort_by_title,它是 sort_by_impl 的派生形式 - 不是类型的 sort_by。这意味着您实际上希望将 my_sort 传递为 sort_by 对象中的 sbp 指针,这是您将使用的实际函数对象。为了说明这一点:

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;

顺便说一句,代码不是异常安全的;考虑用引用计数智能指针替换 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 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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文