4

Это домашнее задание, хотя оно уже представлено с другим подходом.Не удалось специализировать шаблон функции

Я получаю следующее из 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 (который, казалось, очень разумно) I закончилось со следующим сообщением об ошибке

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

main.cpp все тот же, но с некоторыми sli ght в иерархию функтора и исходные файлы. Передовые декларации и т. Д. Не работали, поэтому мне пришлось помещать определения в отдельные файлы.

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

Я действительно не разбираюсь в этом, что мне здесь не хватает? Некоторая операция преобразования или что?
[/ Edit2]

[Edit3]
Последнее и окончательное редактирование, я надеюсь. Я действительно получил эту работу после отладки и перезаписи кода. Это то, что я закончил с, и это лучшее, что я мог сделать

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

Это похоже на работу, как в отдельном проекте (проводя большую часть этого дня баловаться с этим), и в моем реальном проекте, который Я подал несколько дней назад.
Большое спасибо за ваше время и помощь!
[/ Edit3]

+2

Какой тип db_? – Puppy

+0

Возможно, это аспект шаблонов, с которыми я не знаком, но разве вам не нужно предоставлять некоторые аргументы шаблона в первой строке? 'База данных <> db;' –

+0

Оли, шаблон специализирован в производном классе. База данных должна рассматриваться как базовый класс интерфейса/абстрактного класса, где производный класс реализует методы для конкретного типа - std :: list, std :: vector или ... 'C' является членом в базе данных (внутренний контейнер) – citizencane

ответ

8

Я не уверен, что это то, что вызывает проблемы, так как она не имеет ничего общего с специализирующейся 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 может быть вашим абстрактным базовым классом, от которого конкретной сортировки объекты функции выводятся и переопределяются. Надеюсь, это поможет.

EDIT

на основе нового сообщения об ошибке, если я должен был догадаться, что вы пытаетесь сделать что-то вроде этого внутри 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 указателем sbp в объекте sort_by, который является фактическим функциональным объектом, который вы будете использовать. Для иллюстрации:

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 в стек и передайте его адрес. Просто будьте осторожны, чтобы не допустить его уничтожения до его использования. :)

Надеюсь, это поможет. Позвольте мне знать, как это получается!

+0

Спасибо за ваше предложение! Я попробовал, но я получаю еще одну ошибку. Я попытался изменить код, но здесь я не понимаю. Любые другие предложения? Я редактировал свой пост. – citizencane

+0

Большое вам спасибо - вы были очень полезны! Решен и принят. :-) – citizencane