4

I always use const T& to pass a class to a function. Like this:

void foo(const MyType& p)
{
  //...
}

But now I'm confused, why not pass a const T or a T& to a function?

By the way, for built-in types, like int, long long, double, why const T is better than const T& (I remember I've read in Effective C++)

Thanks for answering my questions.

abcdabcd987
  • 2,043
  • 2
  • 23
  • 34
  • 2
    Because they are different things? Reference: yes or no. Const: yes or no. Pick what you need and there ya go. – GManNickG Aug 04 '12 at 02:06

4 Answers4

9

You could pass any of the three (const T, T&, or const T&). They all have different meanings. Up to you whether you want to pass a copy of the object that cannot be modified, a non-const reference to the object, or a const reference to the object. What you choose depends on the semantics of your code. Overall, you would want to choose const T& over const T in order to refrain from having to copy the value over from the caller to this function (save time and memory). Moreover (according to this helpful link), you would want to use const T& over T& whenever you want to refrain from changing neither the value nor the state of the passed reference. This can prevent silly and overlooked coding errors, such as changing a field for testing purposes.

For your question about passing as a parameter a reference to a const primitive type, see this: C++ and QT4.5 - is passing a const int& overkill? Does pass by reference helps in signals/slots?

Community
  • 1
  • 1
ecbrodie
  • 11,246
  • 21
  • 71
  • 120
  • 1
    You should add T&& to your list – walrii Aug 04 '12 at 02:19
  • 1
    It's an R-value reference. Added in c++11. See http://en.wikipedia.org/wiki/C%2B%2B11#Rvalue_references_and_move_constructors or http://thbecker.net/articles/rvalue_references/section_01.html – walrii Aug 04 '12 at 02:25
  • YIPPEE!!! My first accepted answer. Thanks guys (and I hope I didn't break any rules by sharing my excitement...) – ecbrodie Aug 04 '12 at 02:57
1

const T is passed by value (copy is needed), which may be too much for a class while should be ok for built-in types.

T& is passed by reference, which could be modified in the function while const T& can't, so it depends on what you need to do.

Gang YIN
  • 2,509
  • 2
  • 21
  • 25
0

(I remember I've read in Effective C++)

No, you don't, because Scott Meyers wouldn't make such a mistake.

const T& is the best option because it never involves a copy but can still take rvalues. Consider

void foo(int& p);
void foo(const std::string s);
int main() { 
    foo(1); // illegal!
    foo("A reaaaaaaaallllllllllllllllllllllllllllllllllllllllllly long string");
    // Nasty copy
}

If you need a copy of an item, make one in the parameter list (take by value) but there's little reason for this value to be const. Else, use const T&. For some cheap types there's little point not taking by value because you know in advance that copying is cheap.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • 1
    Stroustrup himself basically said that [here](http://stroustrup.com/bs_faq2.html#pointers-and-references). See the *Should I use call-by-value or call-by-reference?* section. Of course I presume that FAQ is fairly old now (when the answer was written, not when the FAQ was last modified), and now we have move constructors, too, which also skews it a bit. – chris Aug 04 '12 at 02:13
  • Oh, maybe it's not _Effective C++_, sorry. Thanks for help – abcdabcd987 Aug 04 '12 at 02:15
  • @DeadMG Today I read _Effective C++_ again, and I found it at Chapter 4 Item 20. You could see the picture: https://twitter.com/abcdabcd987/status/231961897145081856/photo/1 – abcdabcd987 Aug 05 '12 at 03:58
0

Your rule to always pass by const reference is overly general.

Passing by const reference generally indicates that

  • the method is not going to modify the argument
  • that the method may not claim ownership of the argument
  • that the caller guarantees the argument's lifetime will be longer than the call

If you need something different, then you should choose something other than passing by const reference.

walrii
  • 3,472
  • 2
  • 28
  • 47