 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
wkaras@yahoo.com Guest
|
Posted: Sat Jun 11, 2005 10:41 am Post subject: Should template type deduction try "T &" and "const T &" if |
|
|
GCC gives an error when compiling this:
#include <stdio.h>
class S
{
private:
S(const S &s);
public:
S(void) { }
};
void print(const S &i) { printf("made itn"); }
template <typename T>
void call_print(T t) { print(t); }
int main(void)
{
S s;
print(s);
call_print(s);
return(0);
}
Seems like, when the instantiation of call_print fails when
S is deduced for type parameter T, the compiler could then
retry with "S &" for T and then "const S &" for T. Does
the Standard prohibit/allow retrying deduction with
references?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
ta0kira@yahoo.com Guest
|
Posted: Mon Jun 13, 2005 4:12 pm Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
| Quote: | Seems like, when the instantiation of call_print fails when
S is deduced for type parameter T, the compiler could then
retry with "S &" for T and then "const S &" for T. Does
the Standard prohibit/allow retrying deduction with
references?
|
I don't know what compiler you use, but technically you should not be
able to pass something by reference if the copy constructor isn't
accessible. gcc 3.4.0 and later doesn't allow passing by reference if
the copy constructor isn't accessible.
ta0kira
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
wkaras@yahoo.com Guest
|
Posted: Mon Jun 13, 2005 7:45 pm Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
[email]ta0kira (AT) yahoo (DOT) com[/email] wrote:
| Quote: | Seems like, when the instantiation of call_print fails when
S is deduced for type parameter T, the compiler could then
retry with "S &" for T and then "const S &" for T. Does
the Standard prohibit/allow retrying deduction with
references?
I don't know what compiler you use, but technically you should not be
able to pass something by reference if the copy constructor isn't
accessible. gcc 3.4.0 and later doesn't allow passing by reference if
the copy constructor isn't accessible.
ta0kira
|
That doesn't make any sense to me. What would be the reason for
this restriction? A class with private copy constructor(s)
can't be passed by value. So, are you saying the only way
to pass instances of such a class is using a pointer parameter?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Mon Jun 13, 2005 7:47 pm Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
[email]ta0kira (AT) yahoo (DOT) com[/email] writes:
| Quote: | Seems like, when the instantiation of call_print fails when
S is deduced for type parameter T, the compiler could then
retry with "S &" for T and then "const S &" for T. Does
the Standard prohibit/allow retrying deduction with
references?
I don't know what compiler you use, but technically you should not be
able to pass something by reference if the copy constructor isn't
accessible.
|
That's only true for rvalues.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Mon Jun 13, 2005 10:41 pm Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
In article <1118658752.130758.289880 (AT) o13g2000cwo (DOT) googlegroups.com>,
[email]ta0kira (AT) yahoo (DOT) com[/email] writes
| Quote: | Seems like, when the instantiation of call_print fails when
S is deduced for type parameter T, the compiler could then
retry with "S &" for T and then "const S &" for T. Does
the Standard prohibit/allow retrying deduction with
references?
I don't know what compiler you use, but technically you should not be
able to pass something by reference if the copy constructor isn't
accessible. gcc 3.4.0 and later doesn't allow passing by reference if
the copy constructor isn't accessible.
|
I think you must be confused. Pass by value requires a copy ctor,
references do not because they do not involve any form of construction.
BTW Can you please include context when posting a reply to someone
else's post. I have noticed a lot of posts from you today and many of
them have no context.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Mike Gonzalez Guest
|
Posted: Mon Jun 13, 2005 10:43 pm Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
[email]wkaras (AT) yahoo (DOT) com[/email] wrote:
| Quote: | GCC gives an error when compiling this:
#include
class S
{
private:
S(const S &s);
public:
S(void) { }
};
void print(const S &i) { printf("made itn"); }
template
void call_print(T t) { print(t); }
int main(void)
{
S s;
print(s);
call_print(s);
return(0);
}
Seems like, when the instantiation of call_print fails when
S is deduced for type parameter T, the compiler could then
retry with "S &" for T and then "const S &" for T. Does
the Standard prohibit/allow retrying deduction with
references?
|
The rules implicitly prohibit it -- prohibit *retrying*, period
(i.e., retrying in any case, and not specifically retrying with
references).
Once a best match is found, following the rules, that is final.
(think about it: would it really make sense otherwise? Rules
that are not really rules because they can be unpredictably
bent/changed due to other factors, possibly syntax errors in
the instantiated code? -- if there is a syntax error, the
programmer should be forced to correct it, as opposed to
hiding it by trying something else that could be completely
wrong, exhibit undefined behaviour, etc., even if it does end
up having correct syntax)
Carlos
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Tue Jun 14, 2005 10:08 am Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
"wkaras (AT) yahoo (DOT) com" <wkaras (AT) yahoo (DOT) com> writes:
| Quote: | ta0kira (AT) yahoo (DOT) com wrote:
Seems like, when the instantiation of call_print fails when
S is deduced for type parameter T, the compiler could then
retry with "S &" for T and then "const S &" for T. Does
the Standard prohibit/allow retrying deduction with
references?
I don't know what compiler you use, but technically you should not be
able to pass something by reference if the copy constructor isn't
accessible. gcc 3.4.0 and later doesn't allow passing by reference if
the copy constructor isn't accessible.
ta0kira
That doesn't make any sense to me. What would be the reason for
this restriction? A class with private copy constructor(s)
can't be passed by value. So, are you saying the only way
to pass instances of such a class is using a pointer parameter?
|
No, you can't take the address of an rvalue either. Please see C++
Standardization Committee Core Working Group issue 391, though -- the
restriction will be lifted, but your compiler hasn't caught up with
the future yet ;-)
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Jun 14, 2005 7:32 pm Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
[email]ta0kira (AT) yahoo (DOT) com[/email] wrote:
| Quote: | Seems like, when the instantiation of call_print fails when
S is deduced for type parameter T, the compiler could then
retry with "S &" for T and then "const S &" for T. Does the
Standard prohibit/allow retrying deduction with references?
I don't know what compiler you use, but technically you should
not be able to pass something by reference if the copy
constructor isn't accessible. gcc 3.4.0 and later doesn't
allow passing by reference if the copy constructor isn't
accessible.
|
It depends. According to the standard, binding a temporary to a
(const) reference is only legal if there is an accessible copy
constructor (and the compiler may actually make a copy). Not
many compilers enforce this, however.
I'm not sure what the logic is behind the rule. It breaks a few
odd classes where identity is an issue, but which are typically
used as rvalues: my GB_Format would be an example. For the
moment, I "fixed" the problem by declaring a copy constructor,
but not defining it; the correct fix would be to somehow define
copy, but only when the object is in certain specific states.
(For GB_Format, a copy while the text is being formatted doesn't
make sense. A copy before starting, or after everything has
been formatted doesn't hurt, however.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Jun 14, 2005 7:34 pm Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
Francis Glassborow wrote:
| Quote: | In article <1118658752.130758.289880 (AT) o13g2000cwo (DOT) googlegroups.com>,
[email]ta0kira (AT) yahoo (DOT) com[/email] writes
Seems like, when the instantiation of call_print fails when
S is deduced for type parameter T, the compiler could then
retry with "S &" for T and then "const S &" for T. Does
the Standard prohibit/allow retrying deduction with
references?
I don't know what compiler you use, but technically you
should not be able to pass something by reference if the copy
constructor isn't accessible. gcc 3.4.0 and later doesn't
allow passing by reference if the copy constructor isn't
accessible.
I think you must be confused. Pass by value requires a copy
ctor, references do not because they do not involve any form
of construction.
|
§8.5.3/5:
[The initializer expression is neither an lvalue, nor a
class type with an implicite conversion to an lvalue...]
-- Otherwise, reference shall be to a non-volatile const
type (i.e. cv1 shall be const) [...]
-- If the initializer expression is an rvalue, with T2
a class type, and "cv1 T1" is reference-compatbile
with "cv2 T2", the reference is bound in one of the
followind ways (the choice is implementation
defined):
-- The referencer is bound to the object
represented by the rvalue or to a sub-object
within that object.
-- A temporary of type "cv1 T2" [sic] is created,
AND A CONSTRUCTOR IS CALLED to copy the entire
rvalue object into the temporary. The reference
is bound to the temporary or to a sub-object
within the themporary.
THE CONSTRUCTOR that would be used to make the copy
SHALL BE CALLABLE WHETHER OR NOT THE COPY IS
ACTUALLY DONE.
Note the emphasized text.
In fact, I think that there are cases where the copy is
unavoidable. Something, for example, along the lines of:
struct A
{
A() ;
~A() ;
} ;
struct B
{
A a1 ;
A a2 ;
~B() ;
} ;
B f() ;
A const& a = f().a1 ;
I think (I'm not 100% sure) that in this case, the standard
requires that the lifetime of the B object returned from f end
at the end of the full expression ; that B's destructor be
called (and thus, the destructors of B::a1 and B::a2). On the
other hand, the lifetime of the temporary which is actually
bound to the reference is extended to match the lifetime of the
reference.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
wkaras@yahoo.com Guest
|
Posted: Tue Jun 14, 2005 7:36 pm Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
Mike Gonzalez wrote:
| Quote: | wkaras (AT) yahoo (DOT) com wrote:
GCC gives an error when compiling this:
#include
class S
{
private:
S(const S &s);
public:
S(void) { }
};
void print(const S &i) { printf("made itn"); }
template
void call_print(T t) { print(t); }
int main(void)
{
S s;
print(s);
call_print(s);
return(0);
}
Seems like, when the instantiation of call_print fails when
S is deduced for type parameter T, the compiler could then
retry with "S &" for T and then "const S &" for T. Does
the Standard prohibit/allow retrying deduction with
references?
The rules implicitly prohibit it -- prohibit *retrying*, period
(i.e., retrying in any case, and not specifically retrying with
references).
Once a best match is found, following the rules, that is final.
(think about it: would it really make sense otherwise? Rules
that are not really rules because they can be unpredictably
bent/changed due to other factors, possibly syntax errors in
the instantiated code? -- if there is a syntax error, the
programmer should be forced to correct it, as opposed to
hiding it by trying something else that could be completely
wrong, exhibit undefined behaviour, etc., even if it does end
up having correct syntax)
|
I can see your point, but couldn't you make a similar argument
against SFINAE (that it can lead to unpredictable behavior)?
I think it might be a desirable change to the Standard to allow
the compiler to change a parameter type (in templeted or non-
templeted functions) from "T" to "const T &" when necessary to
prevent errors, or simply as an optimization, (to avoid alot of
copying). This would be somewhat analogous to
allowing the compiler to make a variable a register variable if
observable behavior is not changed.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
ta0kira@yahoo.com Guest
|
Posted: Wed Jun 15, 2005 10:52 pm Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: | A const& a = f().a1 ;
|
What if we redefined B as:
struct B
{
B();
A a1;
A a2;
private:
B(const B&);
};
and used B().a1:
A const &a = B().a1;
This way we avoid any use of a copy constructor outside of the context
in question. In my opinion this should not compile because B() is an
rvalue, and either the reference is bound to sub-object a1 or B() is
copied in its entirety into a temporary, but in either case B(const B&)
needs to be visible. If A is given a private copy constructor then the
example (with changes) doesn't compile with Comeau online, but with it
not defined it compiles. So I guess that brings ambiguity upon the
standard as to whether B() or B().a1 is the rvalue in the context of
the citation.
ta0kira
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Fri Jun 17, 2005 10:15 am Post subject: Re: Should template type deduction try "T &" and "const T &" |
|
|
[email]ta0kira (AT) yahoo (DOT) com[/email] wrote:
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
A const& a = f().a1 ;
What if we redefined B as:
struct B
{
B();
A a1;
A a2;
private:
B(const B&);
};
and used B().a1:
A const &a = B().a1;
This way we avoid any use of a copy constructor outside of the
context in question.
|
You still have to copy construct the A. You have an expression
of type A ("B().a1"). An rvalue. You want to bind it to a
const reference. We fall into the case (§8.5.3/5) where "the
initializer expression is an rvalue, with T2 a class type [A],
and "cv1 T1" [A const] is reference-compatible with "cv2 T2"
[A], the reference is bound in one of the following ways
[...]" : the ways are either to bind the reference directly to
the rvalue (or to a sub-object of the rvalue -- but A, here has
no sub-objects), or to bind it to a copy of the rvalue.
We then have to consider the lifetime of the objects. The
lifetime of the object bound to a is the same as that of the
reference. However, as far as I can see, this is the only
object whose lifetime can be extended. The lifetime of the
temporary B() object, which is NOT bound to a reference, must
terminate at the end of the full expression. And since it is
impossible to terminate the lifetime of the B object without
also terminating the lifetime of its a1 member, there is no way
a compiler can bind the a1 member itself to the reference; it
must make a copy, and bind that.
| Quote: | In my opinion this should not compile because B() is an
rvalue, and either the reference is bound to sub-object a1 or
B() is copied in its entirety into a temporary, but in either
case B(const B&) needs to be visible.
|
What does the copy constructor of B have to do with it? I'm not
binding a B to any reference. The initialization expression
doesn't have type B -- the initialization expression has type
A. It is the copy constructor of A which must be accessible.
| Quote: | If A is given a private copy constructor then the example
(with changes) doesn't compile with Comeau online, but with it
not defined it compiles. So I guess that brings ambiguity
upon the standard as to whether B() or B().a1 is the rvalue in
the context of the citation.
|
There's no ambiguity about it. The initialization expression is
B().a1. The type of that expression is A. We are binding an
object of type A to a reference of type A const. The complete
object which gets bound is either the A, or a sub-object of the
A. No B's allowed.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|