Topic: Inherited the same template-named class?
Author: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 1999/11/17 Raw View
Hyman Rosen <hymie@prolifics.com> writes:
> "James Kuyper Jr." <kuyper@wizard.net> writes:
> > You seem to believe that completeness need not be checked for
> > until the time a template is instantiated, rather than at the point it
> > is defined. I'm not saying you're necessarily wrong; I'm not an
> > authority on the standard - but that's not how I read it. Can you cite
> > text from the standard supporting that belief?
>
> 14.6/8 says "The lookup of names dependent on the template parameters
> is postponed until the actual template argument is known." At that
> point, there will be no problem generating the chain of Binary<n>s.
Thank you. That is the quote I was seaching for.
The standard guarantee for recursive derived template classes.
I believe there are many usages as following:
template struct Array<int Dimension> : Array<Dimension-1> { ... };
M. Morita
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/11/11 Raw View
"James Kuyper Jr." <kuyper@wizard.net> writes:
> You seem to believe that completeness need not be checked for
> until the time a template is instantiated, rather than at the point it
> is defined. I'm not saying you're necessarily wrong; I'm not an
> authority on the standard - but that's not how I read it. Can you cite
> text from the standard supporting that belief?
14.6/8 says "The lookup of names dependent on the template parameters
is postponed until the actual template argument is known." At that
point, there will be no problem generating the chain of Binary<n>s.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jim Gewin <jgewin@worldnet.att.net>
Date: 1999/11/06 Raw View
"James Kuyper Jr." <kuyper@wizard.net> writes:
>
>
> Jim Gewin wrote:
> >
> > "James Kuyper Jr." <kuyper@wizard.net> writes:
> ....
> > > True - he mispoke. He should have said that Binary<n/2> is not complete
> > > when it is used as a base class of Binary<n>. Binary<n/2> is complete at
> > > the terminating '}' of it's definition, which is the same place that
> > > Binary<n> definition becomes complete. It is not complete at the point
> > > of it's listing as a base class of Binary<n>.
> > > ---
> >
> > Yes, but isn't there also a rule that a class that is a specialization
> > of a class template will be instantiated automatically if needed as a
> > complete type? (I'm asking, not insisting that this is true, because
> > I've successfully tried it on two well-regarded implementations.)
>
> There are a lot of rules out there; the standard is 776 pages long. Can
> you cite the text of that rule? As you've worded it, it doesn't sound
> right. Template class specializations are instantiated implicitly when a
> complete definition is needed, but being instantiated doesn't turn an
> incomplete template class into a complete one.
>
> In any event, the code in question doesn't instantiate Binary<n/2>
> during the template definition. Nothing is instantiated until
> Binary<100> is explicitly instantiated, at which point Binary<50>,
> Binary<25>, Binary<12>, Binary<6>, Binary<3>, and Binary<1> become
> implicitly instantiated.
>
Now I'm completely confused. I thought that I was trying
to convince you that this was what would happen, and that
you were objecting that it couldn't because the base type
needed to be complete at the time the template was being
parsed.
It now appears that you were only objecting to the original
article's description of how it works, not that it doesn't
work.
Apologies for completely misunderstanding your original
article (and for wasting time and bandwidth on this.)
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/07 Raw View
Jim Gewin wrote:
>
> "James Kuyper Jr." <kuyper@wizard.net> writes:
....
> > In any event, the code in question doesn't instantiate Binary<n/2>
> > during the template definition. Nothing is instantiated until
> > Binary<100> is explicitly instantiated, at which point Binary<50>,
> > Binary<25>, Binary<12>, Binary<6>, Binary<3>, and Binary<1> become
> > implicitly instantiated.
> >
>
> Now I'm completely confused. I thought that I was trying
> to convince you that this was what would happen, and that
> you were objecting that it couldn't because the base type
> needed to be complete at the time the template was being
> parsed.
I apologize for managing to confuse you further. I agree that the above
list of classes should be instantiated, were it legal to instantiate any
of them. I don't think it's legal to instantiate them, because the class
template's definition was ill-formed, due to inheriting from a base
class that isn't complete at the point where the inheritance is
specified. You seem to believe that completeness need not be checked for
until the time a template is instantiated, rather than at the point it
is defined. I'm not saying you're necessarily wrong; I'm not an
authority on the standard - but that's not how I read it. Can you cite
text from the standard supporting that belief?
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jim Gewin <jgewin@worldnet.att.net>
Date: 1999/11/08 Raw View
"James Kuyper Jr." <kuyper@wizard.net> writes:
>
> Jim Gewin wrote:
> >
> > "James Kuyper Jr." <kuyper@wizard.net> writes:
> ....
> > > In any event, the code in question doesn't instantiate Binary<n/2>
> > > during the template definition. Nothing is instantiated until
> > > Binary<100> is explicitly instantiated, at which point Binary<50>,
> > > Binary<25>, Binary<12>, Binary<6>, Binary<3>, and Binary<1> become
> > > implicitly instantiated.
> > >
> >
> > Now I'm completely confused. I thought that I was trying
> > to convince you that this was what would happen, and that
> > you were objecting that it couldn't because the base type
> > needed to be complete at the time the template was being
> > parsed.
>
> I apologize for managing to confuse you further. I agree that the above
> list of classes should be instantiated, were it legal to instantiate any
> of them. I don't think it's legal to instantiate them, because the class
> template's definition was ill-formed, due to inheriting from a base
> class that isn't complete at the point where the inheritance is
> specified. You seem to believe that completeness need not be checked for
> until the time a template is instantiated, rather than at the point it
> is defined. I'm not saying you're necessarily wrong; I'm not an
> authority on the standard - but that's not how I read it. Can you cite
> text from the standard supporting that belief?
Only a shaky argument by analogy with an example in
the standard.
In 14.6.2 [temp.dep] the following (modulo typos) example
occurs (shortened and out of context) in which a class
template inherits from a template parameter:
template<class T> struct Y : T { /* [snipped by JG] */ };
Here, T is presumably incomplete, and yet it is shown
as a base class of Y<T>. This is type-dependence, not
value-dependence, but I would like to believe that the
heirarchy we're talking about is morally equivalent.
Again, I didn't find explicit support, but the following
also works, at least on the two reasonably-modern impl-
ementations I tried (Borland 5.4 and egcs 2.91.60)
template<class T> struct B; // incomplete
template<class T> struct A : B<T> { };
template<class T> struct B { };
int main( )
{
A<double> ad;
}
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 1999/11/03 Raw View
Thank you for an explanation.
"James Kuyper Jr." <kuyper@wizard.net> writes:
> [snip]
> > | class SymmetricMatrix : public Matrix<SymmetricMatrix> {
> > | ...
> > | };
> [snip]
> The base class must be complete, and it is: Matrix<SymmetricMatrix> is
> already complete at that point; we're well past the terminating '}' of
> it's definition. SymmetricMatrix is a template argument of Matrix which
> is incomplete at that point. I didn't find any requirement that template
> arguments must be complete at that point, but I might have missed it.
The latter posting:
"James Kuyper Jr." <kuyper@wizard.net> writes:
> I found a relevant citation in a note in section 14.3.1 p2: "a template
> type argument may be an incomplete type".
So, SymmetricMatrix is right according to the standard.
> > If class SymmetricMatix is OK and my example(Binary) is not OK,
> > what sort of difference between them?
>
> The use of an incomplete class as a base class, rather than as a
> template argument of a base class.
Now I understand the situation.
template<int n> struct Rest { Rest() { std::cout << n; } };
template<int n> struct Binary : Binary<n/2>, Rest<n%2> {};
template<> struct Binary<0> {};
The above would not be legal. But a template argument is so flexible that
the above is rewritten easily like the following:
template<int n> struct Rest { Rest() { std::cout << n; } };
template <class T> struct DummyNest : T {};
template<int n> struct Binary : DummyNest<Binary<n/2> >, Rest<n%2> {};
template<> struct Binary<0> {};
This is certainly legal! ,,,But it is not good for readablity.
It is pity for me. there are some usages like the follwing:
template<int n> struct MyStack : MyStack<n-1> { ... };
template<> struct MyStack<0> {};
template<int n> MyStack<n+1>& up(MyStack<n>& cur) {
return static_cast<MyStack<n+1>&>(cur); }
template<int n> MyStack<n-1>& down(MyStack<n>& cur) {
return static_cast<MyStack<n-1>&>(cur); }
M. Morita
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "J.Barfurth" <techview@bfk-net.de>
Date: 1999/11/04 Raw View
James Kuyper Jr. <kuyper@wizard.net> schrieb in im Newsbeitrag:
381C68DA.A2688DA3@wizard.net...
> Jim Gewin wrote:
> > But Binary isn't a class. Binary<n> inherits from Binary<n/2>,
>
> True - he mispoke. He should have said that Binary<n/2> is not complete
> when it is used as a base class of Binary<n>. Binary<n/2> is complete a=
t
> the terminating '}' of it's definition, which is the same place that
> Binary<n> definition becomes complete. It is not complete at the point
> of it's listing as a base class of Binary<n>.
I think you missed the Point here: Binary (or to be more verbose: templat=
e
<int n> class Binary<n>) isn't a class: It's a class template. Only
Binary<100>, Binary<42>, Binary<0>, .. are classes.
So in some sense it is not true that "Binary<n> inherits from Binary<n/2>=
":
Any Instantiations(tm) of that statement with integral n (n!=3D0, n withi=
n
implementation-defined bounds) are true :-)
Those parts of a template definition that depend on a template parameter =
(in
our case the base class is among them) are mostly left alone when parsing
the template definition. They can be checked for syntactical correctness,
but most names used will not even be looked up at this point.
Much the less will such types be checked for completeness, even if used i=
n a
way that will require a complete type at instantiation time. Offhand I'm =
not
sure, but it might be required that a name used as a template-id must be
known to be one.
Those types have to be complete however when the class is instantiated. A=
nd
in the case of (directly) recursive templates that is (almost [*]) a give=
n:
// simplified code from previous post
template<int n> struct Binary // now 'Binary' is known as a template-=
id
: Binary<n/2>
{
Binary();
}; // definition of template complete
template<> struct Binary<0> { }; // [*] needed to terminate the
recursion, definition of class is also complete
To instantiate a class from class template Binary, the definition of the
template must be complete or the class must have been defined as a
(complete) specialization. When Binary<9> is instantiated, Binary<4> is
needed as base class, so only now it is checked that Binary<4> is of
complete class type. But, as the definition of Binary<n> (as a template) =
is
complete, this complete class type can (and will) be automatically
instantiated by the compiler.
So the explicit instantiation
template class Binary<42>;
will be converted by the compiler to something like
// automatic instantiations
template class Binary<0>; // defined by specialization
template class Binary<1>; // defined by unspecialized template,
requires previous as complete type
template class Binary<2>; // defined by unspecialized template,
requires previous as complete type
template class Binary<5>; // defined by unspecialized template,
requires previous as complete type
template class Binary<10>; // defined by unspecialized template,
requires previous as complete type
template class Binary<21>; // defined by unspecialized template,
requires previous as complete type
// instantiated by user
template class Binary<42>; // defined by unspecialized template,
requires previous as complete type
and similarly when implicitly instantiating the template.
-- J=F6rg
ADDENDUM: Complete Sample, compiles and runs with M$VC6 (!)
#include <iostream>
template<int n> struct Binary : Binary<n/2> { Binary(); };
template<> struct Binary<0> { ~Binary(); };
template struct Binary<43>;
int main()
{ =20
{ Binary<42> tester; }
{ Binary<100> tester; }
{ Binary<2438> tester; }
{ Binary<2000000000> tester; } =20
return EXIT_SUCCESS;
}//main
template <int n> Binary<n>::Binary() { std::cout << (n%2); }
template <> Binary<0>::~Binary() { std::cout << std::endl; }
=20
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/05 Raw View
Jim Gewin wrote:
>
> "James Kuyper Jr." <kuyper@wizard.net> writes:
....
> > True - he mispoke. He should have said that Binary<n/2> is not complete
> > when it is used as a base class of Binary<n>. Binary<n/2> is complete at
> > the terminating '}' of it's definition, which is the same place that
> > Binary<n> definition becomes complete. It is not complete at the point
> > of it's listing as a base class of Binary<n>.
> > ---
>
> Yes, but isn't there also a rule that a class that is a specialization
> of a class template will be instantiated automatically if needed as a
> complete type? (I'm asking, not insisting that this is true, because
> I've successfully tried it on two well-regarded implementations.)
There are a lot of rules out there; the standard is 776 pages long. Can
you cite the text of that rule? As you've worded it, it doesn't sound
right. Template class specializations are instantiated implicitly when a
complete definition is needed, but being instantiated doesn't turn an
incomplete template class into a complete one.
In any event, the code in question doesn't instantiate Binary<n/2>
during the template definition. Nothing is instantiated until
Binary<100> is explicitly instantiated, at which point Binary<50>,
Binary<25>, Binary<12>, Binary<6>, Binary<3>, and Binary<1> become
implicitly instantiated.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 1999/11/01 Raw View
Biju Thomas <b_thomas@ibm.net> writes:
> > template<int n> struct Rest {
> > Rest() { std::cout << n; }
> > };
> >
> > template<int n> struct Binary : Binary<n/2>, Rest<n%2> {
> > };
> >
> > template<> struct Binary<0> {};
> >
> > template struct Binary<100>;
> >
> This is just an explicit instantiation of the template. It is not a
> method declaration. So, it won't print anything to cout.
Thank you. I misunderstood an explicit instantiation.
This explicit instantiation of the template class makes the instantiated
classes which are following:
Binary<0> // 0 specialization case
Binary<1> , Rest<1> // creates two instantiated classes
Binary<3> , Rest<0> // creates two instantiated classes
Binary<6> , Rest<0> // creates only Binary<6> , Rest<0> already created
Binary<12>, Rest<1> // creates only Binary<12>
Binary<25>, Rest<0> // creates only Binary<25>
Binary<50>, Rest<0> // creates only Binary<50>
Binary<100>
But, never construct an object. the constructor shall not be called.
I understand now.
M. Morita
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 1999/11/01 Raw View
"James Kuyper Jr." <kuyper@wizard.net> writes:
> Jim Gewin wrote:
> >
> > Biju Thomas <b_thomas@ibm.net> writes:
> ....
> > > ...
> > >
> >
> > But Binary isn't a class. Binary<n> inherits from Binary<n/2>,
>
> True - he mispoke. He should have said that Binary<n/2> is not complete
> when it is used as a base class of Binary<n>. Binary<n/2> is complete at
> the terminating '}' of it's definition, which is the same place that
> Binary<n> definition becomes complete. It is not complete at the point
> of it's listing as a base class of Binary<n>.
Really? I am confusing now.
I learned many techniques for C++ from the Web Page.
http://www.extreme.indiana.edu/~tveldhui/papers/techniques
This paper introduced me many techniques. For example,
1.4 static polymorphism
| 1.4.3: Solution B: the Barton and Nackman Trick
|
| This trick is often called the "Barton and Nackman Trick", because
| they used it in their excellent book Scientific and Engineering C++.
| Geoff Furnish coined the term "Curiously Recursive Template Pattern",
| which is a good description.
|
| If you haven't seen this trick before, it should have you scratching
| your head. Yes, it is legal.
|
| // Base class takes a template parameter. This parameter
| // is the type of the class which derives from it.
| template<class T_leaftype>
| class Matrix {
| public:
| T_leaftype& asLeaf()
| { return static_cast<T_leaftype&>(*this); }
|
| double operator()(int i, int j)
| { return asLeaf()(i,j); } // delegate to leaf
| };
|
| class SymmetricMatrix : public Matrix<SymmetricMatrix> {
| ...
| };
|
| class UpperTriMatrix : public Matrix<UpperTriMatrix> {
| ...
| };
Here, class SymmetricMatrix is inherited Matrix<SymmetricMatrix>.
According to you, "Matrix<SymmetricMatrix> is complete at the
terminating '}' of it's definition, which is the same place that
SymmetricMatrix definition becomes complete. It is not complete
at the point of it's listing as a base class of SymmetricMatrix."
Therefor this is illegal?
If class SymmetricMatix is OK and my example(Binary) is not OK,
what sort of difference between them?
Thanks in advance.
M. Morita
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jim Gewin <jgewin@worldnet.att.net>
Date: 1999/11/02 Raw View
"James Kuyper Jr." <kuyper@wizard.net> writes:
>
> Jim Gewin wrote:
> >
> > Biju Thomas <b_thomas@ibm.net> writes:
> ....
> > > I am curious to know why it can be considered legal. The standard
> > > clearly says that the classes listed in the base class specifiers should
> > > be complete classes. In the following case, the class Binary is not
> > > complete when it is used as the base class of itself. Is there some
> > > special rules for templates in this regard? I looked in the standard and
> > > couldn't find anything.
> > >
> >
> > But Binary isn't a class. Binary<n> inherits from Binary<n/2>,
>
> True - he mispoke. He should have said that Binary<n/2> is not complete
> when it is used as a base class of Binary<n>. Binary<n/2> is complete at
> the terminating '}' of it's definition, which is the same place that
> Binary<n> definition becomes complete. It is not complete at the point
> of it's listing as a base class of Binary<n>.
> ---
Yes, but isn't there also a rule that a class that is a specialization
of a class template will be instantiated automatically if needed as a
complete type? (I'm asking, not insisting that this is true, because
I've successfully tried it on two well-regarded implementations.)
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/02 Raw View
Masao Morita wrote:
>
> "James Kuyper Jr." <kuyper@wizard.net> writes:
....
> > True - he mispoke. He should have said that Binary<n/2> is not complete
> > when it is used as a base class of Binary<n>. Binary<n/2> is complete at
> > the terminating '}' of it's definition, which is the same place that
> > Binary<n> definition becomes complete. It is not complete at the point
> > of it's listing as a base class of Binary<n>.
> Really? I am confusing now.
Not really; confused perhaps, but not confusing :-)
> I learned many techniques for C++ from the Web Page.
> http://www.extreme.indiana.edu/~tveldhui/papers/techniques
>
> This paper introduced me many techniques. For example,
> 1.4 static polymorphism
> | 1.4.3: Solution B: the Barton and Nackman Trick
> |
> | This trick is often called the "Barton and Nackman Trick", because
> | they used it in their excellent book Scientific and Engineering C++.
> | Geoff Furnish coined the term "Curiously Recursive Template Pattern",
> | which is a good description.
> |
> | If you haven't seen this trick before, it should have you scratching
> | your head. Yes, it is legal.
> |
> | // Base class takes a template parameter. This parameter
> | // is the type of the class which derives from it.
> | template<class T_leaftype>
> | class Matrix {
> | public:
> | T_leaftype& asLeaf()
> | { return static_cast<T_leaftype&>(*this); }
> |
> | double operator()(int i, int j)
> | { return asLeaf()(i,j); } // delegate to leaf
> | };
Class Matrix<T_leaftype> becomes complete at this point.
> |
> | class SymmetricMatrix : public Matrix<SymmetricMatrix> {
> | ...
> | };
Class SymmetricMatrix becomes complete at this point.
> |
> | class UpperTriMatrix : public Matrix<UpperTriMatrix> {
> | ...
> | };
> Here, class SymmetricMatrix is inherited Matrix<SymmetricMatrix>.
> According to you, "Matrix<SymmetricMatrix> is complete at the
> terminating '}' of it's definition, which is the same place that
> SymmetricMatrix definition becomes complete. ...
Not true - those definitions terminate at different '}' characters. See
above.
> ... It is not complete
> at the point of it's listing as a base class of SymmetricMatrix."
> Therefor this is illegal?
The base class must be complete, and it is: Matrix<SymmetricMatrix> is
already complete at that point; we're well past the terminating '}' of
it's definition. SymmetricMatrix is a template argument of Matrix which
is incomplete at that point. I didn't find any requirement that template
arguments must be complete at that point, but I might have missed it.
> If class SymmetricMatix is OK and my example(Binary) is not OK,
I'm not sure about SymmetricMatrix, but I'm willing to believe that it
might be OK.
> what sort of difference between them?
The use of an incomplete class as a base class, rather than as a
template argument of a base class.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/03 Raw View
"James Kuyper Jr." wrote:
....
> is incomplete at that point. I didn't find any requirement that template
> arguments must be complete at that point, but I might have missed it.
I found a relevant citation in a note in section 14.3.1 p2: "a template
type argument may be an incomplete type".
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jim Gewin <jgewin@worldnet.att.net>
Date: 1999/10/31 Raw View
Biju Thomas <b_thomas@ibm.net> writes:
>
> Masao Morita wrote:
> >
> > "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
> > > > Hello.
> > > > I have a question. Is a template class has the base class which has
> > > the
> > > > same template-name OK?
> > >
> > > Yes. Both your examples are legal.
>
> I am curious to know why it can be considered legal. The standard
> clearly says that the classes listed in the base class specifiers should
> be complete classes. In the following case, the class Binary is not
> complete when it is used as the base class of itself. Is there some
> special rules for templates in this regard? I looked in the standard and
> couldn't find anything.
>
But Binary isn't a class. Binary<n> inherits from Binary<n/2>,
Binary<n/4>, and so on down to Binary<0>, which is complete via
specialization.
Simplifying to omit Rest<>, this works fine in egcs-2.91.60
$ cat t.cpp
#include <iostream>
template<int n>
struct Binary : Binary<n/2>
{
Binary( ) { std::cout << n % 2; }
};
template<> struct Binary<0> { };
int main(void)
{
Binary<100> x;
std::cout << std::endl;
return 0;
}
$ g++ --ansi --pedantic -Wall t.cpp 2>&1 | more
t.cpp: In function `int main()':
t.cpp:13: warning: unused variable `struct Binary<100> x'
$ ./a.out
1100100
$
which to my tired brain works out to 96+32+4 == 100.
Or perhaps I completely misunderstood your objection?
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/10/31 Raw View
Jim Gewin wrote:
>
> Biju Thomas <b_thomas@ibm.net> writes:
....
> > I am curious to know why it can be considered legal. The standard
> > clearly says that the classes listed in the base class specifiers should
> > be complete classes. In the following case, the class Binary is not
> > complete when it is used as the base class of itself. Is there some
> > special rules for templates in this regard? I looked in the standard and
> > couldn't find anything.
> >
>
> But Binary isn't a class. Binary<n> inherits from Binary<n/2>,
True - he mispoke. He should have said that Binary<n/2> is not complete
when it is used as a base class of Binary<n>. Binary<n/2> is complete at
the terminating '}' of it's definition, which is the same place that
Binary<n> definition becomes complete. It is not complete at the point
of it's listing as a base class of Binary<n>.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Biju Thomas <b_thomas@ibm.net>
Date: 1999/10/30 Raw View
Masao Morita wrote:
>
> "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
> > > Hello.
> > > I have a question. Is a template class has the base class which has
> > the
> > > same template-name OK?
> >
> > Yes. Both your examples are legal.
I am curious to know why it can be considered legal. The standard
clearly says that the classes listed in the base class specifiers should
be complete classes. In the following case, the class Binary is not
complete when it is used as the base class of itself. Is there some
special rules for templates in this regard? I looked in the standard and
couldn't find anything.
>
> template<int n> struct Rest {
> Rest() { std::cout << n; }
> };
>
> template<int n> struct Binary : Binary<n/2>, Rest<n%2> {
> };
>
> template<> struct Binary<0> {};
>
> template struct Binary<100>;
>
> int main() { std::cout << "\n"; }
>
> But, any compilers does not accept the above.
> I re-wroted last two declarations like the following:
>
> // template struct Binary<100>;
This is just an explicit instantiation of the template. It is not a
method declaration. So, it won't print anything to cout.
>
> int main() {
> Binary<100> dummy;
> std::cout << "\n";
> }
>
> Only KAI-C++ (3.4d) accepted, worked well.
> I think the former one should be work at the compiler which conform to
> the standard. Is that right?
IMHO, this is not legal.
--
Biju Thomas
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 1999/10/27 Raw View
"Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
> > Hello.
> > I have a question. Is a template class has the base class which has
> the
> > same template-name OK?
>
> Yes. Both your examples are legal.
Thank you for replying.
I tryed the actual usage which is the following:
template<int n> struct Rest {
Rest() { std::cout << n; }
};
template<int n> struct Binary : Binary<n/2>, Rest<n%2> {
};
template<> struct Binary<0> {};
template struct Binary<100>;
int main() { std::cout << "\n"; }
But, any compilers does not accept the above.
I re-wroted last two declarations like the following:
// template struct Binary<100>;
int main() {
Binary<100> dummy;
std::cout << "\n";
}
Only KAI-C++ (3.4d) accepted, worked well.
I think the former one should be work at the compiler which conform to
the standard. Is that right?
Thanks in advance.
M. Morita
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 1999/10/25 Raw View
Hello.
I have a question. Is a template class has the base class which has the
same template-name OK?
Is the following legal? (according to the standard?)
template<int n> struct Factorial : Factorial<n-1> {
static const int value = n * Factorial<n-1>::value;
};
template<> struct Factorial<1> {
static const int value = 1;
};
const int fact5 = Factorial<5>::value;
Some compilers accepted the above, but the others rejected.
The following one is the simulated version.
template<int,typename> struct Fclass;
template<int n> struct Factorial {
static const int value = Fclass<n,Factorial<n-1> >::value;
};
template<> struct Factorial<1> {
static const int value = 1;
};
template<int n,class Base> struct Fclass : Base {
static const int value = n * Base::value;
};
All of my compilers accepted the latter version.
I think if the latter is OK, the former should be OK.
Thanks in advance.
M. Morita
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/10/27 Raw View
Masao Morita <m-morita@pdss7.trc.rwcp.or.jp> writes:
> I have a question. Is a template class has the base class which has the
> same template-name OK?
> Is the following legal? (according to the standard?)
> template<int n> struct Factorial : Factorial<n-1> {
> static const int value = n * Factorial<n-1>::value;
> };
No. You can not inherit from an incomplete class.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/10/27 Raw View
Masao Morita <m-morita@pdss7.trc.rwcp.or.jp> wrote in message
news:t0taep7dgnp.fsf@pdss7.trc.rwcp.or.jp...
> Hello.
> I have a question. Is a template class has the base class which has
the
> same template-name OK?
Yes. Both your examples are legal.
Andrei
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]