質問

今日、コンテナ内で一致するシンボルを見つけるための小さな述語を書きました。

しかし、私は問題に直面しています:この述語をクラスのconstメソッド内のstd::find_if呼び出しで使用して、このクラスのメンバーであるコンテナを検索したいです。

しかし、std::findconst_iteratorsも<=>!

で操作できないことに気付いた

一部のC ++参照を確認しましたが、<=>を受け入れる/返す<=>または<=>のバージョンがないようです。私が見たものから、これらのアルゴリズムがイテレータによって参照されるオブジェクトを変更する方法がないので、私はちょうど理由を理解できません。

SGI実装で<=>に文書化する方法は次のとおりです。

  

最初のイテレータiを返します   * i ==となる範囲[first、last)   値。そのようなものがない場合、最後を返します   イテレータが存在します。

役に立ちましたか?

解決

std::findおよびstd::find_ifは、特定のコンテナの*::const_iteratorで確実に操作できます。これらの関数のシグネチャを偶然見て、誤解していますか?

template <class InputIterator, class Type>
InputIterator find(InputIterator first, InputIterator last, const Type& val);

ここでInputIteratorはテンプレート型パラメーターの名前であり、const_iteratorはその要件を満たしていることに注意してください。

または、おそらく、const(つまりconst値を参照するイテレータ)と<=>イテレータ(つまり、それ自体が<=>であるイテレータ)を混同していますか?

他のヒント

std::findstd::find_ifはどちらもイテレータタイプをテンプレートパラメータとして使用するため、 const_iteratorsで操作できます。簡単な例:

#include <vector>
#include <algorithm>
#include <iostream>
int main() { 
    std::vector<int> x;

    std::fill_n(std::back_inserter(x), 20, 2);
    x.push_back(3);

    std::vector<int>::const_iterator b = x.begin();
    std::vector<int>::const_iterator e = x.end();

    std::vector<int>::const_iterator p = std::find(b, e, 3);

    std::cout << *p << " found at position: " << std::distance(b, p) << "\n";
    return 0;
}

これは、適切に機能するC ++コンパイラで受け入れられ、次のような結果を生成する必要があります。

3が位置20で見つかりました

同じ問題が発生しました。メンバーベクトルでfind_ifを呼び出しているメンバー関数があり、メンバー関数constを作成しようとしたときにコンパイラーからエラーが返されました。これは、iteratorではなくconst_iteratorに<=>の戻り値を割り当てていたためであることが判明しました。これにより、コンパイラは、<=>のパラメーターも<=>ではなく<=>でなければならないことを想定しました。これは、<=>メンバーベクトルから取得できませんでした。

万が一あなたが私と同じ理由でここにいる場合:

error: no matching function for call to ‘find(std::vector<int>::const_iterator, std::vector<int>::const_iterator, int)’

const_iteratorとは関係ありません。おそらく#include <algorithm>を忘れただけです:-)

このコードで問題が発生しました:

std::string str;
std::string::const_iterator start = str.begin();
std::string::const_iterator match = std::find(start, str.end(), 'x');

エラーは<!> quot; std :: find <!> quot;に一致するオーバーロードがありませんでした。

必要な修正は、cend()を使用することでした。 cbegin()が必須ではないのはわかりにくいです。なぜ変換が(暗黙的に)大丈夫で、関数パラメータとしてのend()がそうでないのかはわかりません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top