Topic: Why can't a template conversion ctor be the default copy ctor?
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Fri, 16 Feb 2001 05:54:54 GMT Raw View
Victor Bazarov wrote:
>
> "James Kuyper Jr." <kuyper@wizard.net> wrote...
...
> > question. Firstly, its not possible to provide explicit template
> > arguments for a templated constructor (or for a conversion operator).
>
> I don't understand the last sentence. Could you elaborate?
See 14.1.8p5. Constructors and conversion operators don't have function
names. It may look as though they have a function name which matches the
name of the relevant type, but that's not how the standard actually
handles them. What's happening is that the standard allows a type name
to be used in certain contexts that normally call for function names.
However, the thing that precedes explicit template arguments is required
to be the name of the function, not the name of a type. Therefore,
template arguments cannot be provided explicitly for such functions; if
they aren't implicitly deducible, there's no way to invoke the templated
function.
...
> We're not asking about changing those rules. Provide the copy
> c-tor implicitly if not provided by the class, please. Do prefer
> non-templated versions over templated, please. However, I don't
> understand _why_ it couldn't have been made so that a template
> conversion constructor would play the role of the copy constructor.
> Consider (a) and (b) and it seems that you haven't given any
> explanation. Sorry if I just didn't understand what you said.
Sorry, I misunderstood which change you're asking for. There is no
reason why it couldn't have been done that way, just a reason why it's
not the best choice.
The basic reason is that the general code for a templated conversion
constructor usually doesn't do the right thing for the special case
where T is the class type, or at the very least, it doesn't do it as
efficiently as it should. Conversion constructors generally need to do
complicated things that copy constructors don't normally need to worry
about. That means you'd ordinarily want to provide a template
specialization for T==the class type that has different code than the
general case. In other words, you'd want to provide an explicitly
defined copy constructor. More often than not, that specialization would
do precisely the same thing that the implicitly defined copy constructor
would have done. Therefore, preferring the implicitly defined copy
construct over the templated conversion constructor simplifies class
definitions more often than it complicates them.
Your rule would require that many classes which currently can do without
them be given explicitly defined copy constructors, in order to PREVENT
the templated conversion constructor from being invoked.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: Sat, 10 Feb 2001 11:44:25 GMT Raw View
"Andrei Iltchenko" <iltchenko@yahoo.com> wrote...
> [...]
> Because a copy constructor for class X is by definition a non-template
> constructor with its first parameter having type X&, const X&,
volatile X&,
> or const volatile X& (See 12.8/2). And the language requires that a
copy
> constructor for a given class X be always declared. If you don't
declare it,
> it will be declared implicitly (See 12.8/4). The construct:
> > ...
> > template <typename Y> Foo( const Foo<Y>& ); // BBB
> > ...
> is merely a converting constructor.
I think you're missing the point of the question. I believe that
Dan wanted to know WHY it was done that way, why it was chosen
that a copy c-tor is ALWAYS a non-template member. WHY can't the
template conversion c-tor TAKE OVER? What was the reason such
behaviour was NOT allowed?
I answered Dan's question in comp.lang.c++ initially but when the
question of the motivation arose I couldn't give him any specific
information and sent him here, thinking that the kind folk here
would be able to _explain_ the Standard, not just _quote_ it.
Thank you.
Victor
--
Please remove capital A's from my address when replying by mail
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 12 Feb 2001 19:07:44 GMT Raw View
In article <961bms$t3a$1@nnrp.atgi.net>, Victor Bazarov
<vAbazarov@dAnai.com> writes
>I think you're missing the point of the question. I believe that
>Dan wanted to know WHY it was done that way, why it was chosen
>that a copy c-tor is ALWAYS a non-template member. WHY can't the
>template conversion c-tor TAKE OVER? What was the reason such
>behaviour was NOT allowed?
I am not sure that there is a killer argument (well, I think we could
have decided otherwise). But the principle is that non-template
functions are always preferred to template ones. The reasoning
continues: a copy ctor always exists, wither it is defined by the
compiler or it is declared by the programmer. I think that excluding
template instantiations from this process was largely a subjective call.
Those specialising in the rules for templates in the Standard liked it
that way and no-one else felt strongly that it should be otherwise.
--
Francis Glassborow
See http://www.accu.org for details of The ACCU Spring Conference, 2001
(includes many regular participants to C & C++ newsgroups)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Dan" <newz@grog.net>
Date: Mon, 12 Feb 2001 19:10:49 GMT Raw View
"Victor Bazarov" wrote ...
> "Andrei Iltchenko" <iltchenko@yahoo.com> wrote...
> > [...]
> > Because a copy constructor for class X is by definition a non-template
> > constructor with its first parameter having type X&, const X&,
> volatile X&,
> > or const volatile X& (See 12.8/2). And the language requires that a
> copy
> > constructor for a given class X be always declared. If you don't
> declare it,
> > it will be declared implicitly (See 12.8/4). The construct:
> > > ...
> > > template <typename Y> Foo( const Foo<Y>& ); // BBB
> > > ...
> > is merely a converting constructor.
>
> I think you're missing the point of the question. I believe that
> Dan wanted to know WHY it was done that way, why it was chosen
> that a copy c-tor is ALWAYS a non-template member. WHY can't the
> template conversion c-tor TAKE OVER? What was the reason such
> behaviour was NOT allowed?
That's exactly what I would (still) like to understand.
> I answered Dan's question in comp.lang.c++ initially but when the
> question of the motivation arose I couldn't give him any specific
> information and sent him here, thinking that the kind folk here
> would be able to _explain_ the Standard, not just _quote_ it.
I'm glad I'm not the only one who thinks a quote from the standard
and an explanation aren't necessarily one and the same. :)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Dan" <newz@grog.net>
Date: Thu, 8 Feb 2001 23:24:53 GMT Raw View
My question concerns the following template class:
template <typename X> struct Foo
{
Foo( const Foo& ); // AAA
template <typename Y> Foo( const Foo<Y>& ); // BBB
Foo& operator=( const Foo& );
template <typename Y> Foo& operator=( const Foo<Y>& );
};
I realize that the standard says that the two template members
above do not subsume the functionality of their non-template
counterparts, but I don't understand why.
Why can't the default behavior be to use a template conversion
ctor BBB (if one exists) to create the default copy ctor AAA
(unless one is explicitly provided)? Why does the compiler prefer
the copy ctor it generates to one derived from a template con-
version ctor?
In other words, why can't
Foo::Foo( const Foo& ); // AAA
just be a special case of
template <typename Y> Foo::Foo( const Foo<Y>& ); // BBB
when BBB is provided but AAA is not.
I have the same question about the assignment operator.
Thank you.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Andrei Iltchenko" <iltchenko@yahoo.com>
Date: Fri, 9 Feb 2001 16:06:26 GMT Raw View
> My question concerns the following template class:
>
> template <typename X> struct Foo
> {
> Foo( const Foo& ); // AAA
> template <typename Y> Foo( const Foo<Y>& ); // BBB
>
> Foo& operator=( const Foo& );
> template <typename Y> Foo& operator=( const Foo<Y>& );
> };
>
> I realize that the standard says that the two template members
> above do not subsume the functionality of their non-template
> counterparts, but I don't understand why.
I'll restrict the discussion only to converting constructors, as the
situation with assignment operators is very much alike.
Lets consider a particular specialization of the class template Foo, say
Foo<T>. When direct or copy initializing an object of type Foo<T> with
another object of the same type or the type derived from it, the overload
resolution will always prefer the copy constructor Foo<T>::Foo(const Foo&)
to the converting constructor specialization Foo<T>::Foo<T>(const Foo<T>&),
as the former is a member function of a class template specialization, and
the latter is a member function template specialization. And the overload
resolution, when selecting the best viable function, always preferrs a
non-template function over a function template specialization if it cannot
determine the best viable function on the basis of comparing the implicit
conversion sequences that convert each argument of the function call to the
corresponding parameter. See 13.3.3.
> Why can't the default behavior be to use a template conversion
> ctor BBB (if one exists) to create the default copy ctor AAA
> (unless one is explicitly provided)? Why does the compiler prefer
> the copy ctor it generates to one derived from a template con-
> version ctor?
Because a copy constructor for class X is by definition a non-template
constructor with its first parameter having type X&, const X&, volatile X&,
or const volatile X& (See 12.8/2). And the language requires that a copy
constructor for a given class X be always declared. If you don't declare it,
it will be declared implicitly (See 12.8/4). The construct:
> ...
> template <typename Y> Foo( const Foo<Y>& ); // BBB
> ...
is merely a converting constructor.
Regards,
Andrei Iltchenko
Brainbench MVP for C++
http://www.brainbench.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: Mon, 12 Feb 2001 23:34:59 GMT Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote...
> In article <961bms$t3a$1@nnrp.atgi.net>, Victor Bazarov
> <vAbazarov@dAnai.com> writes
> >I think you're missing the point of the question. I believe that
> >Dan wanted to know WHY it was done that way, why it was chosen
> >that a copy c-tor is ALWAYS a non-template member. WHY can't the
> >template conversion c-tor TAKE OVER? What was the reason such
> >behaviour was NOT allowed?
>
> I am not sure that there is a killer argument (well, I think we could
> have decided otherwise). But the principle is that non-template
> functions are always preferred to template ones. The reasoning
> continues: a copy ctor always exists, wither it is defined by the
> compiler or it is declared by the programmer. I think that excluding
> template instantiations from this process was largely a subjective
call.
> Those specialising in the rules for templates in the Standard liked it
> that way and no-one else felt strongly that it should be otherwise.
Thanks, Francis. I guess now it's Dan's move. To be honest I
have no strong preference one way or the other. He might. And
if we could have a discussion here that would lead to some sort
of a consensus, it would be just wonderful.
I know we can't really force "those specialising in the rules for
templates in the Standard" to participate and to give their reasons,
still, the hope dies last, right? :-)
I wonder, are there any documents left that could shed some light
on _how_ some decisions were made or is it all a big secret? Is
this newsgroup the only place left to find out _why_ certain things
are the way they are? I would help folks like I or Dan to learn
the language better...
Victor
--
Please remove capital A's from my address when replying by mail
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Dan" <newz@grog.net>
Date: Tue, 13 Feb 2001 00:30:49 GMT Raw View
"Victor Bazarov" wrote ...
[snip]
> > I am not sure that there is a killer argument (well, I think we could
> > have decided otherwise). But the principle is that non-template
> > functions are always preferred to template ones. The reasoning
> > continues: a copy ctor always exists, wither it is defined by the
> > compiler or it is declared by the programmer. I think that excluding
> > template instantiations from this process was largely a subjective
> call.
> > Those specialising in the rules for templates in the Standard liked it
> > that way and no-one else felt strongly that it should be otherwise.
>
> Thanks, Francis. I guess now it's Dan's move. To be honest I
> have no strong preference one way or the other. He might. And
> if we could have a discussion here that would lead to some sort
> of a consensus, it would be just wonderful.
I don't think I would be justified in claiming that I have a strong
preference about this issue because it simply doesn't come up all that
often. However, when it does, especially in third-party code, I've
always had a memorable lack of fun tracing it.
Personally I think it is counterintuitive for the compiler to use a
silently generated copy ctor when a template conversion ctor exists and,
more importantly, provides the correct copy semantics. Same argument
for the assignment operator.
Perhaps I would not have asked this question if my compilers had
issued a warning to the effect of
WARNING: Please note that I'm not going to use your template
conversion ctor to generate a copy ctor because The
Standard doesn't allow it. Either provide your own
copy ctor explicitly or suffer the wrath of trivial
copy semantics.
Sincerely,
Your Compiler
P.S. Er, check your operator=() while you're at it;
I'm not going to use that template either.
Unfortunately they did not.
> I know we can't really force "those specialising in the rules for
> templates in the Standard" to participate and to give their reasons,
> still, the hope dies last, right? :-)
I want addresses and phone numbers, dammit! I'm going to these peoples'
homes to get answer! ;-)
> I wonder, are there any documents left that could shed some light
> on _how_ some decisions were made or is it all a big secret? Is
> this newsgroup the only place left to find out _why_ certain things
> are the way they are? I would help folks like I or Dan to learn
> the language better...
Emphatically agreed. Sometimes even lowly programmers like myself
like to know why their beloved language is the way it is.
At any rate, Victor, Francis, many thanks to you both.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: joerg.barfurth@attglobal.net (Joerg Barfurth)
Date: Wed, 14 Feb 2001 03:26:20 GMT Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
> I am not sure that there is a killer argument (well, I think we could
> have decided otherwise). But the principle is that non-template
> functions are always preferred to template ones. The reasoning
> continues: a copy ctor always exists, wither it is defined by the
> compiler or it is declared by the programmer. I think that excluding
> template instantiations from this process was largely a subjective call.
> Those specialising in the rules for templates in the Standard liked it
> that way and no-one else felt strongly that it should be otherwise.
I Think there may be two arguments.=20
The weaker one is the following:
struct S { template<class T> S(T) {} }; // (1)
S foo();
S a(1); // (2) uses S::S(int)
S b(a); // (3) here what is instantiated ?
S c( foo() ); // (4) and here ?
Assuming template constructors could be copy constructors, I think in
(1) the implicit declaration of a non-template copy constructor must be
suppressed. [*]
But what specialization should be used at (3) and (4) ?
- Instantiating S::S(S), as template argument deduction dictates, would
have to render most attempts to copy an S ill-formed.
- Instantiating S::S(S const&), as one might hope, seems not to be
justified. There are no const-qualified types in sight.
- Instantiating S(S&) seems not to be warranted by template argument
deduction rules. Also it would still make line (4) illegal.
This just goes to show the limited use of template copy-constructors.
struct A { template<class T> A(T&) {} };=20
isn't much better when rvalues occur. So the only truly usable form in a
class seems to be:
struct B
{
template <class T> B(T const&); // (X)
};
OTOH, in a class template we have some more possibilities, for example
template <class T>
struct C
{
template <class U> C(U const&); // (X) again
template <class U> C(C<U> const&); // (Y)
template <template <class> U> C(U<T> const&); // (Z1)
template <class U, template <class> V> C(V<U> const&); // (Z2)
template <class U> C(C<B<U> > const&); // ?
};
and there are other forms, which, like our first example, cannot really
replace a copy constructor.
We arrive at a more fundamental argument, when we look at how the
compiler can decide whether it should add a implicit declaration for a
copy constructor to the class.
Lets start by observing that the standard seems to allow (afaict) both
making that decision as soon as the class declaration is parsed, and
deferring that decision until an object of the class is constructed in a
way that might involve a copy constructor. At least this seems to be the
intent of 12.8/4 - particularly of not requiring a diagnostic there.=20
Lets now assume a compiler that adds such a declaration when the class
definition is parsed and that template constructors may inihibit (or
override) the implicit declaration.=20
If this compiler encounters one of my example definitions above, it
would have to do template argument deduction against template
constructors callable with one argument for all argument types that are
a cv-qualified version of the class type. If this yields more than one
candidate copy-constructor for the same argument type, it would then
have to use partial ordering to find a 'best' one to declare. If there
isn't a single best match we get multiple, ambiguous declarations (but
we should get no error until that copy c'tor argument type is actually
used). All template specialization declarations obtained this way would
then have to be added to the class definition.
So what the compiler would have to do would be a bunch of wholly new
things:
- Instantiating a specialized member template declaration, but not the
definition.
- Deducing from several potential argument types, still potentially
applying partial ordering, selecting and instantiating a specialization,
all without an actual invocation or other more explicit point of
instantiation.
Alternatively we could change overload resolution rules, so that
function template specializations would be preferred to implicitly
declared non-template functions. IMHO, this would be a very strange
special case and violate the spirit of current overload resolution.
And all this trouble just to produce at least in some cases (see above)
an unusable declaration of a "copy c'tor", that still suffices to
suppress the perfectly fine compiler-declared one.
I think we shouldn't stir up such problems for such a dubious benefit.
Regards, J=F6rg
--=20
J=F6rg Barfurth joerg.barfurth@attglobal.net
<<<<<<<<<<<<< using std::disclaimer; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
Software Developer http://www.OpenOffice.org
StarOffice Configuration http://www.sun.com/staroffice
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 14 Feb 2001 19:32:28 GMT Raw View
Dan wrote:
>
> My question concerns the following template class:
>
> template <typename X> struct Foo
> {
> Foo( const Foo& ); // AAA
> template <typename Y> Foo( const Foo<Y>& ); // BBB
>
> Foo& operator=( const Foo& );
> template <typename Y> Foo& operator=( const Foo<Y>& );
> };
>
> I realize that the standard says that the two template members
> above do not subsume the functionality of their non-template
> counterparts, but I don't understand why.
>
> Why can't the default behavior be to use a template conversion
> ctor BBB (if one exists) to create the default copy ctor AAA
> (unless one is explicitly provided)? Why does the compiler prefer
> the copy ctor it generates to one derived from a template con-
> version ctor?
>
> In other words, why can't
>
> Foo::Foo( const Foo& ); // AAA
>
> just be a special case of
>
> template <typename Y> Foo::Foo( const Foo<Y>& ); // BBB
>
> when BBB is provided but AAA is not.
>
> I have the same question about the assignment operator.
It's a combination of several things.
First of all, there's the rules that require an implicitly declared and
implicitly generated copy ctor. The reason for those rules is mainly to
maintain C compatibility: a struct declared using C syntax will work in
C++ almost the same way it did in C, and a key part of that is due to
the implicitly declared and implicitly defined special member functions.
It's also convenient, because it's often the case that the implicit
versions are precisely what's needed.
Secondly, there's the rule favoring normal functions over templated
functions. That's just an extension of the general rule governing
overload resolution: the more specific match is preferred over the more
general match. There are two main reasons for this. First of all, it
ensures that adding a more general function to a class won't break
existing code which was counting on using the more specific version.
Secondly, and more importantly, you can always invoke the templated
function whose signature matches a given non-template function, by
making the template arguments explicit. If the rules didn't favor the
non-templated function, there wouldn't be any way to call it. It's
assumed that if you bothered to define a function, you presumably want
to be able to call it.
Now, there's two problems with that last reason in the context of your
question. Firstly, its not possible to provide explicit template
arguments for a templated constructor (or for a conversion operator).
Secondly, the copy constructor is defined for you implicitly, so the
fact that it's been defined isn't proof that you wanted it defined. You
could therefore argue that implicitly defined normal functions should
rank lower in overload resolution than explicitly defined templated
ones. However, I'd be very cautious about suggesting any change in the
current overload rules - the consequences of changes in those rules can
be very difficult to anticipate.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: Thu, 15 Feb 2001 19:08:58 GMT Raw View
"James Kuyper Jr." <kuyper@wizard.net> wrote...
> Dan wrote:
> >
> > My question concerns the following template class:
> >
> > template <typename X> struct Foo
> > {
> > Foo( const Foo& ); // AAA
> > template <typename Y> Foo( const Foo<Y>& ); // BBB
> >
> > Foo& operator=( const Foo& );
> > template <typename Y> Foo& operator=( const Foo<Y>& );
> > };
> >
> > I realize that the standard says that the two template members
> > above do not subsume the functionality of their non-template
> > counterparts, but I don't understand why.
> >
> > Why can't the default behavior be to use a template conversion
> > ctor BBB (if one exists) to create the default copy ctor AAA
> > (unless one is explicitly provided)? Why does the compiler prefer
> > the copy ctor it generates to one derived from a template con-
> > version ctor?
> >
> > In other words, why can't
> >
> > Foo::Foo( const Foo& ); // AAA
> >
> > just be a special case of
> >
> > template <typename Y> Foo::Foo( const Foo<Y>& ); // BBB
> >
> > when BBB is provided but AAA is not.
> >
> > I have the same question about the assignment operator.
>
> It's a combination of several things.
>
> First of all, there's the rules that require an implicitly declared and
> implicitly generated copy ctor. The reason for those rules is mainly to
> maintain C compatibility: a struct declared using C syntax will work in
> C++ almost the same way it did in C, and a key part of that is due to
> the implicitly declared and implicitly defined special member functions.
Yes, but as soon as we explicitly define a conversion c-tor or the
copy c-tor we declare the expressed desire to have the struct as
_not_ C-compatible. (a)
> It's also convenient, because it's often the case that the implicit
> versions are precisely what's needed.
>
> Secondly, there's the rule favoring normal functions over templated
> functions.
That rule would not apply if the template conversion constructor
was allowed to take over the copy constructor's tasks. (b)
> That's just an extension of the general rule governing
> overload resolution: the more specific match is preferred over the more
> general match. There are two main reasons for this. First of all, it
> ensures that adding a more general function to a class won't break
> existing code which was counting on using the more specific version.
> Secondly, and more importantly, you can always invoke the templated
> function whose signature matches a given non-template function, by
> making the template arguments explicit. If the rules didn't favor the
> non-templated function, there wouldn't be any way to call it. It's
> assumed that if you bothered to define a function, you presumably want
> to be able to call it.
>
> Now, there's two problems with that last reason in the context of your
> question. Firstly, its not possible to provide explicit template
> arguments for a templated constructor (or for a conversion operator).
I don't understand the last sentence. Could you elaborate?
> Secondly, the copy constructor is defined for you implicitly, so the
> fact that it's been defined isn't proof that you wanted it defined. You
> could therefore argue that implicitly defined normal functions should
> rank lower in overload resolution than explicitly defined templated
> ones. However, I'd be very cautious about suggesting any change in the
> current overload rules - the consequences of changes in those rules can
> be very difficult to anticipate.
We're not asking about changing those rules. Provide the copy
c-tor implicitly if not provided by the class, please. Do prefer
non-templated versions over templated, please. However, I don't
understand _why_ it couldn't have been made so that a template
conversion constructor would play the role of the copy constructor.
Consider (a) and (b) and it seems that you haven't given any
explanation. Sorry if I just didn't understand what you said.
So far the question is unanswered. The only close to the answer
thing was said by Francis. And it basically meant that nobody had
any objections to the proposal to always have those things non-
template, and so it was decided. We still hope to hear any good
arguments _for_ it.
Victor
--
Please remove capital A's from my address when replying by mail
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Steve Clamage <stephen.clamage@sun.com>
Date: Thu, 15 Feb 2001 20:46:38 GMT Raw View
Victor Bazarov wrote:
>
>
> I wonder, are there any documents left that could shed some light
> on _how_ some decisions were made or is it all a big secret? Is
> this newsgroup the only place left to find out _why_ certain things
> are the way they are? I would help folks like I or Dan to learn
> the language better...
>From the beginning of the C++ standards process, committee members
wanted to have some sort of rationale document that would explain
the reasons for all the various decisions. But such a document is a
huge amount of work.
No, that's not true. It's a H-U-U-U-U-U-U-U-U-G-E amount of work.
Committee members are volunteers, who usually have other work that
their employers (or their mortgage holders) require them to do.
Over the years, different people have volunteered to take on the job.
Without exception, each of them left the C++ Committee not long
after volunteering, and never returned.
Occasionally outside people have volunteered, but ran away quickly
once they realize the magnitude of the job.
So, yes, it would be wonderful if the cat wore a bell, but so far,
no one has stepped up to attach a bell to the cat.
Bjarne Stroustrup has done a fine job of explaining the reasoning
behind most language rules (if not every nit) in "The Design and
Evolution of C++". I'm sure there will be more details in future books.
One difference is that he gets paid to write these explanations. :-)
--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]