S
SG
Hi!
This is not a question. I just wanted to share some thoughts on
passing pointers or references to functions. I tend not to think about
it too hard whether to use a pointer or a reference as function
parameter but there are obviously certain (minor) advantages and
disadvantages for each approach.
class A;
void foo(A* ptr);
void bar(A& ref);
void g(A& a) {
foo(&a);
bar(a);
}
We can see at the call sites for foo and bar that foo obviously takes
a pointer whereas bar may take a reference or an object by value (we
need to see the declaration of bar to be sure). I guess that being
explicit about it at the call site may sometimes lead to more readable
code -- at least when the function can mutate the object. But on the
other hand foo might not be able to handle null pointers. The fact
that references always refer to an object (if they're not already
dangling) is nice. A way to do both, being "explicit" at the call site
and avoiding null pointers is what C# achieves with its keyword "ref",
for example. The upcoming C++ standard library will provide something
similar, "reference wrappers". So, i could do something like this:
#include <functional>
template<class T> using refw = std::reference_wrapper<T>;
using std::ref;
using std::cref;
void foobar(refw<A> a);
void g(A& a) {
foobar(ref(a));
}
So, if you feel the need to avoid null pointers and be explicit at the
call site about the function taking a reference you could use a
reference_wrapper like this.
Unfortunately, there is no implicit conversion from
reference_wrapper<U> to reference_wrapper<T> in case U* is implicitly
convertible to T*. I guess this feature has been forgotten or hasn't
yet come up as something nice-to-have.
Cheers,
SG
This is not a question. I just wanted to share some thoughts on
passing pointers or references to functions. I tend not to think about
it too hard whether to use a pointer or a reference as function
parameter but there are obviously certain (minor) advantages and
disadvantages for each approach.
class A;
void foo(A* ptr);
void bar(A& ref);
void g(A& a) {
foo(&a);
bar(a);
}
We can see at the call sites for foo and bar that foo obviously takes
a pointer whereas bar may take a reference or an object by value (we
need to see the declaration of bar to be sure). I guess that being
explicit about it at the call site may sometimes lead to more readable
code -- at least when the function can mutate the object. But on the
other hand foo might not be able to handle null pointers. The fact
that references always refer to an object (if they're not already
dangling) is nice. A way to do both, being "explicit" at the call site
and avoiding null pointers is what C# achieves with its keyword "ref",
for example. The upcoming C++ standard library will provide something
similar, "reference wrappers". So, i could do something like this:
#include <functional>
template<class T> using refw = std::reference_wrapper<T>;
using std::ref;
using std::cref;
void foobar(refw<A> a);
void g(A& a) {
foobar(ref(a));
}
So, if you feel the need to avoid null pointers and be explicit at the
call site about the function taking a reference you could use a
reference_wrapper like this.
Unfortunately, there is no implicit conversion from
reference_wrapper<U> to reference_wrapper<T> in case U* is implicitly
convertible to T*. I guess this feature has been forgotten or hasn't
yet come up as something nice-to-have.
Cheers,
SG