Topic: deriving from a typedef name


Author: jason@cygnus.com (Jason Merrill)
Date: 1996/02/14
Raw View
>>>>> Tim Hollebeek <tim@franck.Princeton.EDU> writes:

> I suspect this is correct behavior, but it sure is confusing, so I
> though I'd double check:

> -----
> template <class T>
> class nVector {
> };

> typedef nVector<double> Vector; // workaround for compiler that
>                                 // doesn't handle <class T = double> well

> class Point : public Vector { // derive from typedef name
> public:
>     Point(const Vector& v) { Vector::Vector(v); } // ***
> };

I think you want

     Point(const Vector& v): Vector(v) { }

This is also well-formed, but just creates a temporary Vector:

     Point(const Vector& v) { Vector(v); }

Jason
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy is
  in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1996/02/08
Raw View
In article 8ds@cnn.Princeton.EDU, tim@franck.Princeton.EDU (Tim Hollebeek) writes:
>I suspect this is correct behavior, but it sure is confusing, so I
>though I'd double check:
>
>-----
>template <class T>
>class nVector {
>};
>
>typedef nVector<double> Vector; // workaround for compiler that
>                                // doesn't handle <class T = double> well
>
>class Point : public Vector { // derive from typedef name
>public:
>    Point(const Vector& v) { Vector::Vector(v); } // ***
>};
>-----
>
>At ***, I get: test.C:9: no method `nVector<double>::Vector'
>for obvious reasons.  However, it's not so obvious if you are just
>looking at the declaration of class Point, and the alternatives:
>
>Vector::nVector<double>(v); // parse error
>nVector<double>::nVector<double>(v); // parse error
>
>don't work; I ended up having to change point to derive from
>nVector<double>.  Are all three of the above really disallowed by
>the standard?  If yes, is there a way to call the copy constructor
>of the inherited class?

I'm having a little trouble understanding what your question is, but I
see in particular two different issues.

1. A typedef name is a synonym for a type, and may be used wherever a
type name is needed. The name of a constructor is not a type name, but
must be spelled the same as its actual class name. So Vector::Vector is
not the name of a constructor for nVector<double>. A construtor name is
nVector<double>::nVector<double>. I believe that can also be written as
Vector::nVector<double>, but I don't think you would want to.

2. You cannot call a constructor directly like a normal function.
So as not to get lost in template syntax, given a type T, you can't
call a constructor directly as T::T() or T::T(t). You can cause a
constructor to be invoked to create an anonymous object, as in
 foo(T());
where function foo takes a T parameter. Similarly, in the Point copy
constructor you could invoke a Vector constructor by its proper name,
but I doubt that is the effect you want. The expression nVector<double>(v)
creates an anonymous copy of v and then destroys it at the end of the block.

---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy is
  in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]