关于c ++:无法专门化函数模板

Failed to specialize function template

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

我正在从Visual Studio 2008获取以下内容

1
error C2893: Failed to specialize function template 'void std::sort(_RanIt,_RanIt,_Pr)'

代码如下

1
2
3
4
5
6
7
8
9
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);
}

函数对象定义为

1
2
3
4
5
6
7
8
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 { ... }
};
...

这里的治疗方法是什么?

[编辑]对不起,也许我应该把遗产说清楚

1
2
template <typename C = std::vector<Media *> >
class Database : public IDatabase<C>

[/编辑]

[编辑2]在工具箱的建议(这似乎很合理)之后,我得到了下面的错误消息

1
error C2664: 'Database<>::sortMedia' : cannot convert parameter 1 from 'sort_by_title' to 'const sort_by &'

main.cpp仍然相同,但对函数层次结构和源文件进行了一些细微的修改。转发声明之类的东西不起作用,所以我必须将定义放在单独的文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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());
    }
};

我真的不是在摸索这个,我在这里错过了什么?一些转换操作,或者什么?[E/EdET2]

[编辑3]希望是最后一次也是最后一次编辑。在调试和重写一些代码之后,我实际上已经完成了这项工作。这就是我最后的结果,这是我能做的最好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);

无论是在一个单独的项目中(今天大部分时间都在处理这个问题),还是在我几天前提交的实际项目中,这似乎都起作用。非常感谢您的时间和帮助![E/EdET3]


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

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

1
2
3
4
5
6
7
8
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中执行类似的操作:

1
2
3
4
Database<std::vector<Media*> > db; // initialized elsewhere...

sort_by_title my_sort;
db.sortDatabase(my_sort);

问题是,my_sortsort_by_title型,是sort_by_impl的派生形式,而不是sort_by型。这意味着您实际上希望将my_sort传递为sort_by对象中的sbp指针,这是您将使用的实际函数对象。举例说明:

1
2
3
4
5
6
7
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并传递其地址。在使用前要小心不要让它被破坏。:)

希望有帮助。告诉我结果如何!