1

STL セットを使用する必要があり、独自の比較関数を定義したいと考えています。しかし、私の要件によれば、この比較関数はグローバルではなく、クラスのパブリック メンバーである必要があります。

//CLASS DEFINITION
class IDENTIFERS
{
public:
         IDENTIFIERS();
         ~IDENTIFIERS();
bool     compare_identifier(int Identifier, int Identifier);

public:
std::set <Identifier, bool(*)(Identifier, Identifier)>      set_instance;

};

//CLASS Constructor
IDENTIFIERS::IDENTIFIERS()
{
std::set <Identifier, bool(*)(Identifier, Identifier)>   set_instance(compare_identifier);
}

上記のようにコードを書くとします。比較関数のプロトタイプが compare_identifier() 関数と一致しないため、コンパイルされません。

それを行う方法はありますか?

4

3 に答える 3

3

非静的メンバー関数は の暗黙的な最初のパラメーターを取るthisため、compare_identifier実際には 3 つのパラメーターがあります。非静的メンバー関数にする必要がある場合は、メンバー関数の暗黙的な最初のパラメーターを のインスタンスにバインドする必要があります。IDENTIFIERSたとえば、

#include <set>
#include <functional>

struct Identifier { int id; };

class IDENTIFERS
{
public:
  IDENTIFERS() : set_instance(std::bind(&IDENTIFERS::compare_identifier,
                                        this,                                               
                                        std::placeholders::_1,
                                        std::placeholders::_2))
  {}
  bool  compare_identifier(const Identifier& lhs, const Identifier& rhs)
  {
    return lhs.id < rhs.id;
  }

public:
  std::set <Identifier, std::function<bool(const Identifier&, const Identifier&)>> set_instance;

};
于 2013-06-22T12:23:04.077 に答える
0

サンプル コードには多くのエラーがあります。

0 番目のエラーはスタイルに多少関連しています。クラスは all-lowercase-with-underscores または CamelCase という名前にする必要があります。

最初のエラー:

bool compare_identifier(int Identifier, int Identifier);

次のように、両方の関数パラメーターに同じ識別子を使用することはできません (また、スタイル関連の関数パラメーターはすべて小文字またはキャメルケースにする必要があります)。

bool compare_identifier(int id1, int id2);

2番目のエラーは次のとおりです。

std::set <Identifier, bool(*)(Identifier, Identifier)> set_instance;

class Identifierあなたがどこかに持っていると仮定します。あなたのクラスはIDENTIFIERS. クラスがある場合、関数が次のようになっていると想定する必要があります。Identifiercompare_identifier

bool compare_identifier(const Identifier& id1, const Identifier& id2);

あなたのset_instance宣言は次のようなものです:

std::set<Identifier, bool(*)(const Identifier&, const Identifier&)> set_instance;

3 番目のエラーは、コンストラクターが想定していること (set_instanceメンバーの構築) を行わず、(構文的に有効な場合) というローカル変数を構築することですset_instance。したがって、コンストラクターは次のようになります。

IdentifierBucket::IdentifierBucket() :
  set_instance(std::bind(compare_identifier, this, _1, _2)) {
}

しかし、これはすべて議論の余地があります...コンパレーターsetもあなたが思っていることをしませんが(2つのアイテムが等しいかどうかを確認してください)、順序を与えます(デフォルトのコンパレーターはstd::less...

あなたが本当に欲しいのは次のようなものです:

#include <set>
#include <functional>

struct Identifier {};

struct IdentifierComparator {
  IdentifierComparator() {};
  bool operator()(Identifier id1, Identifier id2); // WRITE THIS
};

class IdentifierBucket {
public:
  IdentifierBucket() {};
  ~IdentifierBucket() {};

private:
  std::set <Identifier, IdentifierComparator> set_instance;
};
于 2013-06-22T13:03:38.733 に答える
0

compare_identifier() staticこれを解決する最も簡単な方法は、作ることです。Identifierが別の場所で定義されていると仮定して、コンパイルできるようにコードを修正する方法を次に示します。

// Watch for the typo (missing 'I') in your code above
class IDENTIFIERS // Note, all-uppercase names are usually reserved for macros
{
public:
    IDENTIFIERS();

    // N.B: This function needs to take two `Identifier`s as its arguments
    // (not two `int`s)    
    static bool compare_identifier(Identifier const &l, Identifier const& r)
    {
       return l.custom_less_than(r);
    }

    // typedefs can make your code more readable, especially with function pointers.
    typedef bool (*identifier_comparator)(Identifier const &l, Identifier const& r);
    typedef std::set<Identifier, identifier_comparator> identifier_set;
    identifier_set set_instance;
};

IDENTIFIERS::IDENTIFIERS()
    :set_instance(compare_identifier) // Initialise here
{
    // Don't shadow `set_instance` in the body of the constructor!
} 

次のコメント

compare_identifier() static( でIDENTIFIERS) を作成しても、 のメンバーのアクセシビリティには影響しませIdentifier classん。Identifier2 つのオブジェクトを比較するロジックはIdentifier、次のように 内に存在する必要があります。

class Identifier
{
public:
    // If you define this, then you won't need to specify a custom comparator
    bool operator <(Identifier const& r) const
    {
        // return true if `*this` is logically less-than `r`; false otherwise.
    }

    bool custom_less_than(Identifier const& r) const
    {
        // Some other way of comparing objects. Perhaps reverse-alphabetically
        // or similar.
        // return true if `*this` is logically less-than `r`; false otherwise.
    } 
};

...または無料の関数private内ですが、これらはメンバーにアクセスできません。

于 2013-06-22T12:48:10.117 に答える