Have a look at this hypothetical header file:
template <class T>
class HungryHippo {
public:
void ingest(const T& object);
private:
...
}
Now, for a HungryHippo<string>
it makes sense that you would want to ingest
references to the strings -- copying a string might be very expensive! But for a HungryHippo<int>
it makes way less sense. Passing an int
directly can be really cheap (most compilers will do it in a register), but passing a reference to an int
is an extra needless level of indirection. This all applies to returning values as well.
Is there some way to suggest to the compiler "hey, I'm not going to modify the argument, so you decide whether to pass by value or by reference, depending on what you think is better"?
Some things that may be relevant:
- I can fake this effect manually by writing
template <class T, bool PassByValue> class HungryHippo
and then specializing onPassByValue
. If I wanted to get really fancy, I could even inferPassByValue
based onsizeof(T)
andstd::is_trivially_copyable<T>
. Either way, this is a lot of extra work when the implementations are going to look pretty much the same, and I suspect the compiler can do a much better job of deciding whether to pass by value than I can. The libc++ project seems to solve this by inlining a lot of functions so the compiler can make the choice one level up, but in this case let's say the implementation ofAs explained in the comments, all template functions areingest
is fairly complicated and not worth inlining.inline
by default.