Mostly for fun I've tried implementing std::ref myself, and I came up with this:
template<typename T>
struct ref_wrapper {
ref_wrapper(T& t) : ref(t) {}
T& ref;
operator T&() const {
return ref;
}
};
template<typename T>
ref_wrapper<T> ref(T& t) {
return ref_wrapper{t}; // Ooops
}
template<typename T>
ref_wrapper<const T> cref(const T& t) {
return ref_wrapper{t}; // Ooops
}
where on the lines marked as // Ooops I have mistakely made use of CTAD because I was compiling with -std=c++17. By changing ref_wrapper to ref_wrapper<T> and ref_wrapper<const T> in the two cases corrects this.
Then I've had a peek into /usr/include/c++/10.2.0/bits/refwrap.h.
On the one hand, I see that my implementation of ref/cref closely resembles that of std::ref/std::cref.
On the other hand, I see that std::reference_wrapper is around 60 lines long! There's a lot of stuff in there, including noexcept, macros, copy ctor, copy operator=, get.
I think most of that is not relevant to the use of std::reference_wrapper only as a slave to std::ref, but there's something which could be relevant, such as constructor taking a universal reference.
So my question is: what are the parts of std::reference_wrapper necessary and sufficients for std::ref to work, with respect to my skinny attempt?
I've just realized that there's a possible implementation of std::reference_wrapper on cppreference (which is less noisy than the one from GCC). Even here, however, there are things I don't undertand the reason of, such as operator().
Aucun commentaire:
Enregistrer un commentaire