Suppose I have a function that takes an argument of type T.
It does not mutate it, so I have the choice of passing it by const reference const T&
The guys here are correct that most of the time it doesn't matter when the sizeof the struct/class is small and there's no fancy copy constructor. However that's no excuse for being ignorant. Here's what happens in some modern ABIs like x64. You can see that on that platform, a good threshold for your rule of thumb is to pass by value where the type is a POD type and sizeof() <= 16, since it will get passed in two registers. Rules of thumb are good, they keep you from wasting time and limited brainpower on the little decisions like this that don't move the needle.
However, sometimes it will matter. When you've determined with a profiler that you have one of those cases (and NOT before unless it's super obvious!), then you need to understand the low level details - not hear comforting platitudes about how it doesn't matter, which SO is full of. Some things to keep in mind: