0

std::set_union<...> アルゴリズムのカスタム特殊化の次の例があります。http://en.cppreference.com/w/cpp/algorithm/set_unionからの実装を適応させました。

実装をカスタマイズする必要があるのは、両方のセットから要素のペアを作成したいからです。範囲がオーバーラップする (交差) 場合、出力には std::pair<*first_iter, *second_iter> が含まれます。

要素が最初のセットに一意である場所では、出力は概念的に std::pair<*first_iter, second_type()> になり、最後に要素が 2 番目のセットに一意である場所では、出力は std::pair になります。 .

コードは機能しますが、私のカスタマイズでは、 std::pair<> のいずれかの側の構成要素をデフォルトにするために LoadableFile 型をハードコーディングする必要がありました (上記の特殊化の 3 つのケースのうちの 2 つに応じて)。Merge テンプレート引数から型情報にアクセスしてその型を知る方法はありますか (それはPairMaker < Loadable, Loadable >であり、特殊化をハードコーディングすることなくデフォルト コンストラクト Loadable() ですか?

これは私のカスタマイズです:

// customized set_union that merges elements from both sets
// when the elements are unique in InputIt1 - merge constructs
// a pair with a default constructed type of InputIt1
template<typename InputIt1, typename InputIt2,
    typename OutputIt, typename Compare, 
    typename Merge>
OutputIt custom_set_union(
    InputIt1 first1, InputIt1 last1,
    InputIt2 first2, InputIt2 last2,
    OutputIt d_first, Compare comp,
    Merge merge)
{
    // example implementation taken and modified from cppreference.com
    for (; first1 != last1; ++d_first) {
        // empty second set
        if (first2 == last2) {
            // return std::copy(first1, last1, d_first);
            // equivalent of std::copy(...) from cppreference.com
            while (first1 != last1) {
                //*d_first++ = *first++;
                *d_first++ = merge(*first1++, LoadableFile());
            }
            return d_first;
        }
        if (comp(*first2, *first1)) {
            //*d_first = *first2++;
            *d_first = merge(LoadableFile(), *first2++);
        } else {
            //*d_first = *first1;
            // @JC note added *first2 as merge arg2 - overlapping region
            *d_first = merge(*first1, *first2);
            if (!comp(*first1, *first2))
                ++first2;
            ++first1;
        }
    }
    // return std::copy(first2, last2, d_first);
    // equivalent of std::copy(...) from cppreference.com
    while (first2 != last2) {
        //*d_first++ = *first++;
        *d_first++ = merge(LoadableFile(), *first2++);
    }
    return d_first;
};

OutputIt に適した要素を作成するために必要なフレームワークを提供するために、次のように、OutputIt に適したペアを作成する Merge クラスがあります。

/**
 * PairMaker helper struct to make pairs of objects from
 * 2 different types of sets templated on types A & B
 * must have default constructors - pair types A & B must
 * have default constructors
 */
template<typename A, typename B>
struct PairMaker {
    std::pair<A, B> operator() (const A& a, const B& b) const {
        return std::make_pair(a, b);
    }
};

私の場合、実際に特殊化を使用するには、次のように呼び出します。

    auto comp = [](const LoadableFile& lhs, const LoadableFile& rhs) {
        return lhs.getRelativePath().filename() < rhs.getRelativePath().filename();
    };

    PairMaker<LoadableFile, LoadableFile> pairMaker;
    std::set<std::pair<LoadableFile,LoadableFile>> resultSet;
    custom_set_union(rLocalFileInfo.cbegin(), rLocalFileInfo.cend(),
        rModuleFileInfo.cbegin(), rModuleFileInfo.cend(), 
        std::inserter(resultSet, resultSet.end()),
        comp, pairMaker);
4

0 に答える 0