5

これは宿題ですが、別のアプローチで既に提出されています。

Visual Studio 2008 から以下を取得しています

エラー C2893: 関数テンプレート 'void std::sort(_RanIt,_RanIt,_Pr)' の特殊化に失敗しました

コードは次のとおりです。

main.cpp
    データベース <> デシベル;
    デシベル.loadDatabase();
    db.sortDatabase(sort_by_title());  

データベース.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 *> >
クラス データベース : public IDatabase<C>

[/編集]

[Edit2]
Toolbox からの提案 (非常に妥当と思われる) の後、次のエラー メッセージが表示されました。

エラー C2664: 'Database<>::sortMedia': パラメーター 1 を 'sort_by_title' から 'const sort_by &' に変換できません

main.cpp は同じですが、ファンクター階層とソース ファイルにわずかな変更が加えられています。前方宣言などが機能しなかったため、定義を別のファイルに入れる必要がありました。

検索.h
struct_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 {
        リターン (*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> {
公衆:
    sort_by(sort_by_impl *sbp) : sbp_(sbp) {};
    bool operator()(const Media *l, const Media *r) const {
        return (*sbp_)(l, r);
    }
プライベート:
    sort_by_impl *sbp_;
};

main.cpp
    デシベル.sortDatabase(&sort_by_title());

データベース.cpp
void Database<C>::sortDatabase(const sort_by &s) {
    std::sort(db_.begin(), db_.end(), s);

これは、別のプロジェクト (この日の大部分をこれをいじるのに費やしています) と、数日前に提出した実際のプロジェクトの両方で機能しているようです。
お時間をいただき、ありがとうございました。
[/Edit3]

4

1 に答える 1

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特定のソート関数オブジェクトが派生してオーバーライドする抽象基本クラスにすることができます。お役に立てば幸いです。

編集

新しいエラーメッセージに基づいて、私が推測しなければならなかった場合、あなたはこのようなことを内部で行おうとしていますsortMedia

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

sort_by_title my_sort;
db.sortDatabase(my_sort);

問題はmy_sort、タイプが-sort_by_titleの派生形式であり、タイプではないことです。つまり、実際に渡すオブジェクトのポインタになりたいということです。これは、使用する実際の関数オブジェクトです。説明する:sort_by_implsort_bymy_sortsbpsort_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に、スタックでを宣言してそのアドレスを渡すだけです。使用前に破壊しないように注意してください。:)

うまくいけば、それがお役に立てば幸いです。どうなるか教えてください!

于 2011-01-07T23:48:10.710 に答える