basics of templates

P

puzzlecracker

something that befuddled me for years, please disambiguate my
confusion:

Two verstions of functional templates:
A) B)
template <typename T> template <typename T>
void f(T a, T b); void f(T * a, T* b);
int a;
int &b=a;

When we call f(a); why would call instantiate a pointer template
(B) instead of (A)?
why is it different - given that both are -underlined- text
substitution after type deduction?



and pointer type is an actual type.

my understadning is if we only have B) the call would result
in
void (int ** a, int * *b); apparently it doesn't...

Thanks.

...cracker.
 
L

Larry I Smith

puzzlecracker said:
something that befuddled me for years, please disambiguate my
confusion:

Two verstions of functional templates:
A) B)
template <typename T> template <typename T>
void f(T a, T b); void f(T * a, T* b);
int a;
int &b=a;

When we call f(a); why would call instantiate a pointer template
(B) instead of (A)?
why is it different - given that both are -underlined- text
substitution after type deduction?



and pointer type is an actual type.

my understadning is if we only have B) the call would result
in
void (int ** a, int * *b); apparently it doesn't...

Thanks.

...cracker.

Well, I'm not sure I understand the question.
Your templates each require 2 args; so calling "f(a)" should
produce a compile error.

Here's a simple prog with comments:

#include <iostream>

template <typename T>
void f(T a, T b)
{
std::cout << "f(T a, T b)" << std::endl;
}

template <typename T>
void f(T * a, T * b)
{
std::cout << "f(T * a, T * b)" << std::endl;
}

// test 2 f() templates. the output should be:
// f(T a, T b)
// f(T a, T b)
// f(T * a, T * b)
int main()
{
int a = 0; // simple int
int& b = a; // ref to int
int * c = &a; // pointer to int

// produces a compile error - no single-arg f() template
// exists
//f(a);

// pass by value - calls f(T a, T b)
f(a, a);

// pass by ref (same as pass by value) - calls f(T a, T b)
f(b, b);

// pass a pointer - calls f(T * a, T * b)
f(c, c);

return 0;
}

Regards,
Larry
 
L

Larry I Smith

Larry said:
Well, I'm not sure I understand the question.
Your templates each require 2 args; so calling "f(a)" should
produce a compile error.

Here's a simple prog with comments:

#include <iostream>

template <typename T>
void f(T a, T b)
{
std::cout << "f(T a, T b)" << std::endl;
}

template <typename T>
void f(T * a, T * b)
{
std::cout << "f(T * a, T * b)" << std::endl;
}

// test 2 f() templates. the output should be:
// f(T a, T b)
// f(T a, T b)
// f(T * a, T * b)
int main()
{
int a = 0; // simple int
int& b = a; // ref to int
int * c = &a; // pointer to int

// produces a compile error - no single-arg f() template
// exists
//f(a);

// pass by value - calls f(T a, T b)
f(a, a);

// pass by ref (same as pass by value) - calls f(T a, T b)
f(b, b);

// pass a pointer - calls f(T * a, T * b)
f(c, c);

return 0;
}

Regards,
Larry

Note that you can not have BOTH:

// pass args by value
template <typename T>
void f(T a, T b) { }

- AND -

// pass args by ref
template <typename T>
void f(T & a, T & b) { }

because they are interchangeable and the compiler will
complain that they are ambiguous. and it doesn't know which
one to call.

Regards,
Larry
 
N

niklasb

puzzlecracker said:
something that befuddled me for years, please disambiguate my
confusion:

Two verstions of functional templates:
A) B)
template <typename T> template <typename T>
void f(T a, T b); void f(T * a, T* b);
int a;
int &b=a;

I think you mean: int* b = &a;
In other words, b is a pointer-to-int.
When we call f(a); why would call instantiate a pointer template
(B) instead of (A)?
why is it different - given that both are -underlined- text
substitution after type deduction?

and pointer type is an actual type.

my understadning is if we only have B) the call would result
in
void (int ** a, int * *b); apparently it doesn't...

The B template is instantiated with T=int so each of the parameters
has type int*.

So why isn't the call ambiguous? After all, each of the overloaded
function templates is a possible match for the arguments. The reason
it is not ambiguous, and that B is selected, is that B is "more
specialized" than A.

The relevant section of the standard is called function template
partial ordering, or something like that. It's a little difficult
to explain the actual rules, but intuitively you might observe that
template B matches fewer argument types; thus it is less specialized.

More formally, there's a test you can do. Look at template A and
imagine instantiating it with T being some arbitrary type -- call
it Foo -- which gives us:

// template A instaniated with T=Foo
void f(Foo a, Foo b);

Now ask, could you instantiate template B for these same arguments?
No we could not, because no matter what type you substitute for T
in template B, the parameters will be pointers.

Next we do the same test in reverse. Instantiate B with T being
another arbitrary type which we'll call Bar:

// template B instantiated with T=Bar
void f(Bar* a, Bar* b);

Now ask the same question again. Could you instantiate template A
for these arguments? Yes you could. In general, no matter what type
you use to instantiate template B, there is an instantiation of
template A that would accept the same arguments.

For the above reasons, B is more specialized than A, and the overload
rules cause B to be selected.
 
F

Fraser Ross

The relevant section of the standard is called function template
partial ordering, or something like that. It's a little difficult
to explain the actual rules, but intuitively you might observe that
template B matches fewer argument types; thus it is less specialized.


A typo is at the end. B is more specialised than A.

Fraser.
 

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
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top