Template notation

D

desktop

I am trying to understand the following template:

template <typename T>
inline T const& max (T const& a, T const& b) {
return a < b ? b : a;
}

does it say that the function max returns a constant reference to T of
any type?

I have never seen a function returning references before, does it mean
that it returns the address of the value returned?

normally the address of eg. an integer is:

int x = 22;

&x

but in the above function its more like:

x&
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

I am trying to understand the following template:

template <typename T>
inline T const& max (T const& a, T const& b) {
return a < b ? b : a;

}

does it say that the function max returns a constant reference to T of
any type?

It returns a const reference of type T, yes.
I have never seen a function returning references before, does it mean
that it returns the address of the value returned?

No, pointers are not references, a reference can be seen as an alias
for a variable, so the following is true for references but not for
pointers:

int i = 1;
int& j = i; // j is a reference to i
if (&i == &j)
// Always true

So you can see that if you take the address of a reference to an
object you get the address of the object while if you take the address
of a pointer to a object you get that pointer's address.

Another example:

void foo(int& i) {
++i;
}

int k = 1;

foo(k);

Now, in the function foo(), the i we are changing is the same integer
as k, so it's another name but the same variable.
 
D

desktop

Erik said:
It returns a const reference of type T, yes.


No, pointers are not references, a reference can be seen as an alias
for a variable, so the following is true for references but not for
pointers:

int i = 1;
int& j = i; // j is a reference to i
if (&i == &j)
// Always true

So you can see that if you take the address of a reference to an
object you get the address of the object while if you take the address
of a pointer to a object you get that pointer's address.

Another example:

void foo(int& i) {
++i;
}

int k = 1;

foo(k);

Now, in the function foo(), the i we are changing is the same integer
as k, so it's another name but the same variable.


Ok guess it the same as in java where Object myobj = new Object()
generates the reference myobj to an Object.


The parameters to the max template:

max (T const& a, T const& b)

are also references, why pass a reference to a template instead of the
"real" object?
 
V

Victor Bazarov

desktop said:
[..]
Ok guess it the same as in java where Object myobj = new Object()
generates the reference myobj to an Object.

I don't think it's appropriate to say that. There are no references
in Java (Just like there are no pointers in Java).
The parameters to the max template:

max (T const& a, T const& b)

are also references, why pass a reference to a template instead of the
"real" object?

Please see FAQ section 8, section 31, the rest of it too. If you have
questions left after that, ask.

V
 
S

Salt_Peter

Ok guess it the same as in java where Object myobj = new Object()
generates the reference myobj to an Object.

Java might call that a reference, its closer to a C++ pointer.
Java has no equivalence of a C++ reference.
The parameters to the max template:

max (T const& a, T const& b)

are also references, why pass a reference to a template instead of the
"real" object?

Its the other way around. passing by reference IS passing the "real"
variable using an alias.
Passing by value only modifies a local variable and more importantly -
it invokes a constructor, usually a copy ctor.
 
J

Juha Nieminen

Salt_Peter said:
Passing by value only modifies a local variable and more importantly -
it invokes a constructor, usually a copy ctor.

Quite curiously, passing by reference may in some cases actually
produce less efficient code (depending on the compiler, of course).

Using gcc 3.3.5 with maximum optimizations (-O3 -march=pentium4)
this code:

template<typename T>
inline const T& max(T const& a, T const& b) { return a < b ? b : a; }
int foo(int a, int b) { return max(a, b); }

produces this asm:

..LFB5:
pushl %ebp
..LCFI0:
movl %esp, %ebp
..LCFI1:
movl 12(%ebp), %edx
leal 8(%ebp), %eax
leal 12(%ebp), %ecx
cmpl %edx, 8(%ebp)
popl %ebp
cmovge %eax, %ecx
movl (%ecx), %eax
ret

Removing the references should *in theory* produce an identical
result, but it doesn't. The code:

template<typename T>
inline const T max(T const a, T const b) { return a < b ? b : a; }
int foo(int a, int b) { return max(a, b); }

produces this asm:

..LFB5:
pushl %ebp
..LCFI0:
movl %esp, %ebp
..LCFI1:
movl 8(%ebp), %ecx
movl 12(%ebp), %eax
popl %ebp
cmpl %eax, %ecx
cmovge %ecx, %eax
ret

The 10 opcodes have been reduced to 8. Granted, I'm not a Pentium4
expert and I can't tell for sure that the latter code is faster than
the former, but I'm pretty convinced.
 
S

Salt_Peter

Quite curiously, passing by reference may in some cases actually
produce less efficient code (depending on the compiler, of course).

Using gcc 3.3.5 with maximum optimizations (-O3 -march=pentium4)
this code:

template<typename T>
inline const T& max(T const& a, T const& b) { return a < b ? b : a; }
int foo(int a, int b) { return max(a, b); }

produces this asm:

.LFB5:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
movl 12(%ebp), %edx
leal 8(%ebp), %eax
leal 12(%ebp), %ecx
cmpl %edx, 8(%ebp)
popl %ebp
cmovge %eax, %ecx
movl (%ecx), %eax
ret

Removing the references should *in theory* produce an identical
result, but it doesn't. The code:

template<typename T>
inline const T max(T const a, T const b) { return a < b ? b : a; }
int foo(int a, int b) { return max(a, b); }

produces this asm:

.LFB5:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
movl 8(%ebp), %ecx
movl 12(%ebp), %eax
popl %ebp
cmpl %eax, %ecx
cmovge %ecx, %eax
ret

The 10 opcodes have been reduced to 8. Granted, I'm not a Pentium4
expert and I can't tell for sure that the latter code is faster than
the former, but I'm pretty convinced.

With simple variables thats expected and in this case pass by value is
fine if T remains a primitive type. The moment you start passing
complex variables by value (and invoking additional copy constructors)
the results won't be the same.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top