pass-by-reference to function vs. to function template

This code does not compile:
1
2
3
4
5
void f(const int& val) {...}
int main() {
   f(1);
   return 0;
}


but this is correct (why?):
1
2
3
4
5
6
template <typename T>
void f(const T& val) {...}
int main() {
   f(1);
   return 0;
}


Is there any difference between
1
2
template <typename T>
void f(const T& val) {...}


and
1
2
template <typename T>
void f(const T val) {...}

? Thanks.

Last edited on
closed account (zwA4jE8b)
1) because when you call f(1) i believe '1' is an r-value and therefor has no address.

if you did something like
1
2
int a = 1;
f(a);


that should work because a is an l-value and has an address.

If I am wrong, someone please correct me.


2) the difference is that one is a reference and one is a copy of the parameter.
& will refer to the original address of the parameter being passed so...

1
2
3
4
5
6
7
8
9
10
11
12
13
template <typename T>
void f(const T& val) 
{
 val = 6;  //val is 'referring' to a, a.k.a. using the same memory address
}

int main()
{
 int a = 5;
 f(a);
 std::cout << a;  //a will now be 6
return 0;
}


however
1
2
3
4
5
6
7
8
9
10
11
12
13
template <typename T>
void f(const T val) 
{
 val = 6; //val is a copy of a - with a different memory location.
}

int main()
{
 int a = 5;
 f(a);
 std::cout << a;  //a will now 5
return 0;
}

Last edited on
It makes sense. If we explain parameter-passing for function in the same way as for function template, the following code should not compile:
1
2
3
4
5
6
template <typename T>
void f(const T& val) {...}
int main() {
   f(1);
   return 0;
}


because we are passing "1" into it ("1" has no address to refer to). In fact, it not only compiles, but works. I am confused indeed. Why?
I just compiled
1
2
3
4
5
void f(const int& val) {...}
int main() {
   f(1);
   return 0;
}


And it worked fine on VC++ 8 (2008)
closed account (1vRz3TCk)
I don't see a problem with it either (Apple LLVM 2.1, GCC 4.2).
It is because the compiler is being smart and inlining the function call in the cases where it works.
closed account (zwA4jE8b)
so jsmith, was my first response correct? or am i on the wrong track?
AFAIK it is allowed to bind a constant reference to a temporary.
¿But why inline the function?
Last edited on
closed account (1vRz3TCk)
CreativeMFS wrote:
so jsmith, was my first response correct? or am i on the wrong track?

The initialiser for a reference to a constant object (e.g. const T&) need not be an lvalue and due to type conversion doesn't even need to be the same type.

First any implicit type conversion is carried out, then a temporary is created and used to initialise the reference.

1
2
double& dr = 1; // Error: lvalue needed
const double& cdr = 1; // ok 
Last edited on
closed account (zwA4jE8b)
I was doing some reading and came across this
Only the address of the actual original object is put on the stack, not the entire object.


anyway,

so CodeMonkey, i understand case 1, but are you saying in your case 2 that '1' is converted to 'double' and the const forces a temporary to be created? and this temporary has an address?
Topic archived. No new replies allowed.