Template Type Inference of Reference

A

Andrew Tomazos

Please consider...

class C { ... }

void g(C& c) { ... alters state of c ... }

template <class F, class P>
void h(F f, P p)
{
f(p);
}

void main()
{
C c1;
h(g,c1);
}

The question is: will the local variable c1 be modified?

In other words, when the type P is calculated, will it be calculated
as 'C' or 'C&' ? and why?

Thanks,
Andrew.
 
V

Victor Bazarov

Andrew said:
Please consider...

class C { ... } ;

void g(C& c) { ... alters state of c ... }

template <class F, class P>
void h(F f, P p)
{
f(p);

Did you mean

g(p);

?
}

void main()

int main()
{
C c1;
h(g,c1);
}

The question is: will the local variable c1 be modified?

In other words, when the type P is calculated, will it be calculated
as 'C' or 'C&' ? and why?

AIUI, the type deduction happens from the arguments passed. In your
case, the 'P' argument of the 'h' template will be deduced as 'C', not
as 'a reference to C' because such is the type of the expression 'c1'.
You can verify it by checking the type of 'p' using 'typeid' operator or
the type of 'c1' in 'main'.

The local variable of the 'h' function (instantiated from the template)
will be modified by the call to 'g' (I hope it was a typo that you wrote
'f' there).

V
 
N

Neelesh

Please consider...

    class C { ... }

    void g(C& c) { ... alters state of c ... }

    template <class F, class P>
    void h(F f, P p)
    {
        f(p);
    }

    void main()

int main(); . Please refer http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.3
    {
        C c1;
        h(g,c1);
    }

The question is: will the local variable c1 be modified?
No, because h takes the second parameter by value, so a copy of c1
will be passed.
To avoid this copy and make sure that a reference is passed, either
change h to take second parameter by reference, or explicitly give
template argument types like this:
h said:
In other words, when the type P is calculated, will it be calculated
as 'C' or 'C&' ?  and why?

as C, because type of c1 is C. (Note that this has nothing to do with
the declaration of c1 being "C c1". Even if the declaration would had
been "C& c1 = c;" still P will get inferred as C, becuase what you are
passing is an object of type C. (In c++ you can't decide at the call-
time whether you are passing a reference or value, and hence I believe
that the only way to make sure that a reference is passed in this case
is one of the two ways mentioned above.)

Thanks.
 
N

Neelesh

                      ;





Did you mean

           g(p);

?

Isn't f(p) appropriate? f is the first parameter to h, which can be a
function pointer, and p could be a valid argument to it. For example,
in the current case F can be void(*)(C&) and P can be C.

This code (using f(p) ) compiles well for me (of course by making
necessary minimal changes).
 
A

Andrew Tomazos

    template <class F, class P>
    void h(F f, P p)
    {
        f(p);

Did you mean

           g(p);

?
[snip]
The local variable of the 'h' function (instantiated from the template)
will be modified by the call to 'g' (I hope it was a typo that you wrote
'f' there).

No, I really meant f(p). F will be deduced as a function pointer
type, so you can pass g as a parameter to the template and then call
it. This is how functor objects are formed.
-Andrew.
 
V

Victor Bazarov

Neelesh said:
Isn't f(p) appropriate? f is the first parameter to h, which can be a
function pointer, and p could be a valid argument to it. For example,
in the current case F can be void(*)(C&) and P can be C.

This code (using f(p) ) compiles well for me (of course by making
necessary minimal changes).

Certainly. I totally spaced out on the 'f' argument, since the question
was about 'p', and 'f' played no role (or so it seemed).

Thank you for correcting me.

V
 
T

Thomas J. Gritzan

Victor said:
AIUI, the type deduction happens from the arguments passed. In your
case, the 'P' argument of the 'h' template will be deduced as 'C', not
as 'a reference to C' because such is the type of the expression 'c1'.
You can verify it by checking the type of 'p' using 'typeid' operator or
the type of 'c1' in 'main'.

No, you can't use typeid to check if something is a reference. When you
apply typeid to a reference to some type, it returns a type_info
refering to the type itself. Top-level cv-qualifier are ignored, too:

typeid(D) == typeid(const D); // true
typeid(D) == typeid(const D&); // true

See 5.2.8/4-5 [expr.typeid].
 
V

Victor Bazarov

Thomas said:
Victor said:
AIUI, the type deduction happens from the arguments passed. In your
case, the 'P' argument of the 'h' template will be deduced as 'C', not
as 'a reference to C' because such is the type of the expression 'c1'.
You can verify it by checking the type of 'p' using 'typeid' operator or
the type of 'c1' in 'main'.

No, you can't use typeid to check if something is a reference. When you
apply typeid to a reference to some type, it returns a type_info
refering to the type itself. Top-level cv-qualifier are ignored, too:

typeid(D) == typeid(const D); // true
typeid(D) == typeid(const D&); // true

See 5.2.8/4-5 [expr.typeid].

Dang! And I know I've read this before... Oh well, I guess my memory
does not work as well any more as it used to...

V
 

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,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top