The issue is clear with the following code:
#include <functional>
#include <iostream>
#include <vector>
int main() {
//std::vector<int> a, b;
int a = 0, b = 0;
auto refa = std::ref(a);
auto refb = std::ref(b);
std::cout << (refa < refb) << '\n';
return 0;
}
If I use the commented std::vector<int> a, b;
instead of int a = 0, b = 0;
, then the code does not compile on any of GCC 5.1, clang 3.6, or MSVC'13. In my opinion, std::reference_wrapper<std::vector<int>>
is implicitly convertible to std::vector<int>&
which is LessThanComparable, and thus it should be LessThanComparable itself. Could someone explain this to me?
Are you certain that
Is doing what it is supposed to? Take this for example
Which results in
Ultimately
Creates two separate vectors of integers called a and b, both of which have no contents; this is not how one would declare a single vector with members a and b.
Declares two separate integers called a and b, which each have a value of 0. Those two code snippets declare completely different variables and should not be used interchangeably.
The issue is that the non-member
operator<
forstd::vector
is a function template:Implicit conversions are not considered when doing template type deduction here, [temp.arg.explicit] emphasis on if:
But in this case, the parameter type does participate in deduction. That's why it can't be found. Had we written our own non-template
operator<
:Your code would work as expected. To use the generic one though, you will have to explicitly pull out the reference: