I have the following function to merge output for 2 containers :
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++;
}
}
The problem is that I get a warning message at line ("comparison of integers of different signs") :
if (*src1_begin <= *src2_begin) {
Here is a use case :
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);
}
Is there any solution for it?
How can I silence the warning, given that I am certain that the comparison is actually ok?
If you're sure that both containers contain values in the same range you can cast the values to the same type. Following code removes the warning:
#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);
}
On Godbolt you can see that the compiler produces almost the same output.