2

私は3つのフィールドを含む構造体の配列を持っています:

struct data{
   int s;
   int f;
   int w;   
};

struct data a[n];

フィールド f に基づいて構造体の配列をソートするために、独自の比較演算子を使用しています。

bool myf( struct data d1,const struct data d2){
   return d1.f < d2.f ; 
}

上記の演算子は、組み込みsort()関数で正常に機能します。

 sort(a,a+n,myf);

しかし、それは関数ではupper_bound()機能しません:

 upper_bound(a,a+n,someValue,myf); 

誰が私がどこで間違っているのか教えてもらえますか? 私の比較演算子は間違っていますか? 間違っている場合、なぜそれが機能するのsort() function and not upper_bound()ですか?

私はコンパイルで次のようになっています:

    /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_algo.h: In function     ‘_FIter std::upper_bound(_FIter, _FIter, const _Tp&, _Compare) [with _FIter = data*, _Tp =     int, _Compare = bool (*)(data, data)]’:
   prog.cpp:37:   instantiated from here

    /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_algo.h:2243: error: conversion from ‘const int’ to non-scalar type ‘data’ requested
4

2 に答える 2

4

ここで実際に必要なのはoperator<、タイプを作成することだけです。

inline bool operator<( const data& lhs, const data& rhs ) {
    return lhs.f < rhs.f;
}

標準アルゴリズムが魔法のように機能します。

C++ では、C のような型を参照する場合は必要なく、コピーを回避するために const 参照structで渡したい場合。

編集 0:

上記<は、タイプの標準比較演算子をオーバーロードします。次のように暗黙的に使用します。

data values[N];
// ... populate
std::sort( values, values + N );

または標準ファンクターで明示的に:

std::sort( values, values + N, std::less<data>());

編集1:

_Tp = intコンパイラが警告で教えてくれるのを見ましたか? ではなく、のdata3 番目の引数としてのインスタンスを渡す必要があります。upper_boundint

data xxx = { 0, 1, 7 };
auto iter = std::upper_bound( values, values + N, xxx );

次のように、整数と比較するためのオーバーロードを作成することもできます。

inline bool operator<( const data& lhs, int rhs ) {
    return lhs.f < rhs;
}

inline bool operator<( int lhs, const data& rhs ) {
    return lhs < rhs.f;
}

元の呼び出しが機能するようにします。

于 2012-10-01T14:52:02.113 に答える
1

主に、upper_boundカスタムの並べ替えを受け入れるオーバーロードが次の 4 つのパラメーターを取るため、機能していません。

// http://en.cppreference.com/w/cpp/algorithm/upper_bound
template< class ForwardIt, class T, class Compare >
ForwardIt upper_bound( ForwardIt first, ForwardIt last, const T& value, 
                       Compare comp );

operator<あなたのタイプに紹介する別の回答で提案されました。ただし、特定のソートのためだけにこれを行わないでください。type にとって実際に意味がある場合にのみ、比較演算子を導入してください。

このルールに従わないと、将来のプログラマーがあなたの型を使用して、なぜ機能しないのに機能するのか疑問に思うかもしれません。あなたの将来の邪悪な双子も、彼の目的のために別の分類を使用したいと思うかもしれません。

たとえば、complex-datatype クラス、SIMD クラス (のような) には意味がありますが、たとえばクラスには特定の意味std::valarrayはありません。Employee

Employee foo, bar;

if (bar > foo) {
    // is bar taller than foo?
    // is bar older than foo?
    // is bar working better than foo?
    // is bar bigger newbie than foo?
}

代わりに、次のようにすることができます。

namespace employee_ordering {
    struct by_name_ascending {
        bool operator() (Employee const &lhs, Employee const &rhs) const {
            return lhs.name() < rhs.name();
        }
    };

    struct by_name_descending {
        bool operator() (Employee const &lhs, Employee const &rhs) const {
            return lhs.name() > rhs.name();
        }
    }
};

....


upper_bound(first, last, ..., employee_ordering::by_name_ascending());
于 2012-10-01T15:48:56.123 に答える