c++:警告比较迭代器

c++ : warning comparing iterators

我有以下功能来合并 2 个容器的输出:

template <typename IteratorType1, typename IteratorType2>

void Merge(IteratorType1 src1_begin, IteratorType1 src1_end,
           IteratorType2 src2_begin, IteratorType2 src2_end,
           ostream& out) {
    size_t i1 = 0, i2 = 0;
    size_t src1_size = std::distance(src1_begin, src1_end);
    size_t src2_size = std::distance(src2_begin, src2_end);

    while (i1 < src1_size && i2 < src2_size) {
        if (*src1_begin <= *src2_begin) {
            out << *src1_begin << std::endl;
            src1_begin++;
            i1++;
        } else {
            out << *src2_begin << std::endl;
            src2_begin++;
            i2++;
        }
    }
    while (i1 < src1_size) {
        out << *src1_begin << std::endl;
        src1_begin++;
        i1++;
    }
    while (i2 < src2_size) {
        out << *src2_begin << std::endl;
        src2_begin++;
        i2++;
    }
}

问题是我在行(“比较不同符号的整数”)处收到一条警告消息:

if (*src1_begin <= *src2_begin) {

这是一个用例:

template <typename T, typename S>
void MergeSomething(const list<T>& src1, const vector<S>& src2, ostream& out) {
    Merge(src1.cbegin(), src1.cend(), src2.cbegin(), src2.cend(), out);
}

int main()
{
    vector<int> v2{65, 75, 85, 95};
    set<unsigned> my_set{20u, 77u, 81u};

    cout << "Merging set and vector:"sv << endl;
    MergeSomething(my_set, v2, cout);
}

有什么解决办法吗?

既然我确定比较确实没问题,我该如何消除警告?

如果您确定两个容器都包含相同范围内的值,则可以将这些值转换为相同的类型。以下代码删除警告:

#include <climits>
#include <iostream>
#include <list>
#include <vector>
using namespace std::literals;

template <typename IteratorType1, typename IteratorType2>
void Merge(IteratorType1 src1_begin, IteratorType1 src1_end,
           IteratorType2 src2_begin, IteratorType2 src2_end,
           std::ostream& out) {
    auto src1_size = std::distance(src1_begin, src1_end);
    auto src2_size = std::distance(src2_begin, src2_end);
    decltype(src1_size) i1 = 0, i2 = 0;

    while (i1 < src1_size && i2 < src2_size) {
        if (static_cast<decltype(*src2_begin)>(*src1_begin) <= *src2_begin) {
            out << *src1_begin << std::endl;
            src1_begin++;
            i1++;
        } else {
            out << *src2_begin << std::endl;
            src2_begin++;
            i2++;
        }
    }
    while (i1 < src1_size) {
        out << *src1_begin << std::endl;
        src1_begin++;
        i1++;
    }
    while (i2 < src2_size) {
        out << *src2_begin << std::endl;
        src2_begin++;
        i2++;
    }
}

template <typename T, typename S>
void MergeSomething(const std::list<T>& src1, const std::vector<S>& src2, std::ostream& out) {
    Merge(src1.cbegin(), src1.cend(), src2.cbegin(), src2.cend(), out);
}

int main()
{
    std::vector<int> v2{65, 75, 85, 95};
    std::list<unsigned> my_set{20u, 77u, 81u};

    std::cout << "Merging set and vector:"sv << std::endl;
    MergeSomething(my_set, v2, std::cout);
}

Godbolt 上,您可以看到编译器产生几乎相同的输出。

这是另一个(我认为更优雅的解决方案)我刚来

template <typename IteratorType1, typename IteratorType2>
void Merge(IteratorType1 src1_begin, IteratorType1 src1_end,
           IteratorType2 src2_begin, IteratorType2 src2_end,
           ostream& out) {
    size_t i1 = 0, i2 = 0;
    size_t src1_size = std::distance(src1_begin, src1_end);
    size_t src2_size = std::distance(src2_begin, src2_end);

    while (i1 < src1_size && i2 < src2_size) {
        if (std::less<>()(*src1_begin, *src2_begin)) {
            out << *src1_begin << std::endl;
            src1_begin++;
            i1++;
        } else {
            out << *src2_begin << std::endl;
            src2_begin++;
            i2++;
        }
    }
    while (i1 < src1_size) {
        out << *src1_begin << std::endl;
        src1_begin++;
        i1++;
    }
    while (i2 < src2_size) {
        out << *src2_begin << std::endl;
        src2_begin++;
        i2++;
    }
}