问题描述
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++;
}
}