C++:警告比较迭代器

问题描述

我有以下功能来合并 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,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++;
    }
}