www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Covariant problem

reply Zarathustra <adam.chrapkowski gmail.com> writes:
error:
function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides but is not
covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

I don't know how to fix this problem. What does 'covariant' mean?
Jul 23 2008
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides but is 
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns type CPoint3d[], but the derived class is returning CPoint2d[]. In order for this to work, CPoint2d[] must be implicitly castable to CPoint3d[], which probably isn't true. In order to diagnose the problem exactly, we would have to see code. At least the class hierarchy. -Steve
Jul 23 2008
next sibling parent reply Lars Ivar Igesund <larsivar igesund.net> writes:
Steven Schveighoffer wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides but is
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns type CPoint3d[], but the derived class is returning CPoint2d[]. In order for this to work, CPoint2d[] must be implicitly castable to CPoint3d[], which probably isn't true. In order to diagnose the problem exactly, we would have to see code. At least the class hierarchy. -Steve

Arrays are not implicitly castable (not even explicitly afaik) to another type, no matter how they are related. -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Jul 23 2008
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Lars Ivar Igesund" wrote
 Steven Schveighoffer wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides but 
 is
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns type CPoint3d[], but the derived class is returning CPoint2d[]. In order for this to work, CPoint2d[] must be implicitly castable to CPoint3d[], which probably isn't true. In order to diagnose the problem exactly, we would have to see code. At least the class hierarchy. -Steve

Arrays are not implicitly castable (not even explicitly afaik) to another type, no matter how they are related.

From http://www.digitalmars.com/d/1.0/arrays.html A dynamic array T[] can be implicitly converted to one of the following: a.. U[] b.. void[] Where U is a base class of T. -Steve
Jul 23 2008
parent Lars Ivar Igesund <larsivar igesund.net> writes:
Steven Schveighoffer wrote:

 "Lars Ivar Igesund" wrote
 Steven Schveighoffer wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides but
 is
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns type CPoint3d[], but the derived class is returning CPoint2d[]. In order for this to work, CPoint2d[] must be implicitly castable to CPoint3d[], which probably isn't true. In order to diagnose the problem exactly, we would have to see code. At least the class hierarchy. -Steve

Arrays are not implicitly castable (not even explicitly afaik) to another type, no matter how they are related.

From http://www.digitalmars.com/d/1.0/arrays.html A dynamic array T[] can be implicitly converted to one of the following: a.. U[] b.. void[] Where U is a base class of T.

Hmm, was it always that way? In any case, implicitly casting from U[] to T[] doesn't work, and if you do it explicitly, the result won't work (and IIRC doing foreach and cast was not an acceptable general solution), and as such T[] is not co-variant return type for U[]. -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Jul 23 2008
prev sibling next sibling parent reply Zarathustra <adam.chrapkowski gmail.com> writes:
Steven Schveighoffer Wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides but is 
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns type CPoint3d[], but the derived class is returning CPoint2d[]. In order for this to work, CPoint2d[] must be implicitly castable to CPoint3d[], which probably isn't true. In order to diagnose the problem exactly, we would have to see code. At least the class hierarchy. -Steve

Ok, thanks. I understand it now. CPoint2d class is inherited by CPoint3d. Both classes have same named functions with this difference that one return CPoint2d object and second CPoin3d object. Is possible to extort to call correct function (not from parent class). It's strange, because CPoint2d can be casted to CPoint3d but not inversely.
Jul 23 2008
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Zarathustra" wrote
 Steven Schveighoffer Wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides but 
 is
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns type CPoint3d[], but the derived class is returning CPoint2d[]. In order for this to work, CPoint2d[] must be implicitly castable to CPoint3d[], which probably isn't true. In order to diagnose the problem exactly, we would have to see code. At least the class hierarchy. -Steve

Ok, thanks. I understand it now. CPoint2d class is inherited by CPoint3d. Both classes have same named functions with this difference that one return CPoint2d object and second CPoin3d object. Is possible to extort to call correct function (not from parent class). It's strange, because CPoint2d can be casted to CPoint3d but not inversely.

I'm not quite sure how to interpret your statement. It might be better to understand by showing some stub code. Fill in where you see ???: class CPoint2d : ??? { } class CPoint3d : ??? { } class CPolygon2d : ??? { ???[] getPoints() {} } class CPolygon3d : ??? { ???[] getPoints() {} } -Steve
Jul 23 2008
parent reply Zarathustra <adam.chrapkowski gmail.com> writes:
Steven Schveighoffer Wrote:

 
 "Zarathustra" wrote
 Steven Schveighoffer Wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides but 
 is
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns type CPoint3d[], but the derived class is returning CPoint2d[]. In order for this to work, CPoint2d[] must be implicitly castable to CPoint3d[], which probably isn't true. In order to diagnose the problem exactly, we would have to see code. At least the class hierarchy. -Steve

Ok, thanks. I understand it now. CPoint2d class is inherited by CPoint3d. Both classes have same named functions with this difference that one return CPoint2d object and second CPoin3d object. Is possible to extort to call correct function (not from parent class). It's strange, because CPoint2d can be casted to CPoint3d but not inversely.

I'm not quite sure how to interpret your statement. It might be better to understand by showing some stub code. Fill in where you see ???: class CPoint2d : ??? { } class CPoint3d : ??? { } class CPolygon2d : ??? { ???[] getPoints() {} } class CPolygon3d : ??? { ???[] getPoints() {} } -Steve

class CPoint3d{ } class CPoint2d : CPoint3d{ } class CPolygon3d{ CPoint3d [] getPoints() {} } class CPolygon2d : CPolygon3d{ CPoint2d [] getPoints() {} }
Jul 24 2008
next sibling parent reply Zarathustra <adam.chrapkowski gmail.com> writes:
Koroskin Denis Wrote:

 On Thu, 24 Jul 2008 15:19:59 +0400, Zarathustra  
 <adam.chrapkowski gmail.com> wrote:
 
 Steven Schveighoffer Wrote:

 "Zarathustra" wrote
 Steven Schveighoffer Wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides  



 is
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns


 CPoint3d[], but the derived class is returning CPoint2d[].  In order  


 this to work, CPoint2d[] must be implicitly castable to CPoint3d[],  


 probably isn't true.

 In order to diagnose the problem exactly, we would have to see  


 least the class hierarchy.

 -Steve

Ok, thanks. I understand it now. CPoint2d class is inherited by CPoint3d. Both classes have same named functions with this difference that one return CPoint2d object and

 CPoin3d object. Is possible to extort to call correct function (not  

 parent class). It's strange, because CPoint2d can be casted to  

 but not inversely.

I'm not quite sure how to interpret your statement. It might be better to understand by showing some stub code. Fill in where you see ???: class CPoint2d : ??? { } class CPoint3d : ??? { } class CPolygon2d : ??? { ???[] getPoints() {} } class CPolygon3d : ??? { ???[] getPoints() {} } -Steve

class CPoint3d{ } class CPoint2d : CPoint3d{ } class CPolygon3d{ CPoint3d [] getPoints() {} } class CPolygon2d : CPolygon3d{ CPoint2d [] getPoints() {} }

Well, it *should* work based on current semantics, because CPoint2d[] implicitly castable to CPoint3d[]. Moreover, it compiles with D2 but doesn't with D1. However, it is error-prone (as I showed previously) and is therefore better to avoid. Besides, it's an arguable design to inherit CPoint2d from CPoint3d :)

Thanks, but Inheriting is ok, because point2d is also point3d but with this difference it is located on a plane. Point2d have coordinates x, y, z in relation to the space coordinate system and coordinates x, y in relation to the plane coordinate system. But it's only thad by the way ;p I use D1. Hmm in my opinion it should work. Ok little more code: class CPoint3d{ //______________________________________ // ::>> Attributes <<:: // //______________________________________ // << fields >> private long m_x; private long m_y; private long m_z; //... //______________________________________ // << properties >> // property x //______________________________________ public long x(long o_x){ return this.m_x = o_x; } public long x( ){ return this.m_x ; } // property y //______________________________________ public long y(long o_y){ return this.m_y = o_y; } public long y( ){ return this.m_y ; } // property z //______________________________________ public long z(long o_z){ return this.m_z = o_z; } public long z( ){ return this.m_z ; } //... } class CPoint2d : CPoint3d{ //______________________________________ // ::>> Attributes <<:: // //______________________________________ // << fields >> private long m_x; private long m_y; //... //______________________________________ // << properties >> // property x //______________________________________ public long x(long o_x){ return this.m_x = o_x; } public long x( ){ return this.m_x ; } // property y //______________________________________ public long y(long o_y){ return this.m_y = o_y; } public long y( ){ return this.m_y ; } //... } class CPolygon3d{ //______________________________________ // ::>> Attributes <<:: // //______________________________________ // << fields >> //... private CPoint3d [] m_points; //... //______________________________________ // << properties >> //... // property getPoints //______________________________________ public CPoint3d [] getPoints(){ return this.GetPoints; } //... //______________________________________ // ::>> Methods <<:: // //... //______________________________________ // << operations >> //... private CPoint3d [] GetPoints() in{ //... } out{ //... } body{ //... } } class CPolygon2d : CPolygon3d{ //______________________________________ // ::>> Attributes <<:: // //______________________________________ // << fields >> //... private CPoint2d [] m_points; //... //______________________________________ // << properties >> //... // property getPoints //______________________________________ public CPoint2d [] getPoints(){ return this.GetPoints; } // <- error is here //... //______________________________________ // ::>> Methods <<:: // //... //______________________________________ // << operations >> //... private CPoint2d [] GetPoints() in{ //... } out{ //... } body{ //... } } For me it's unreasonable because CPoint3d can not be casted to CPoint2d :( Ech ;/
Jul 24 2008
next sibling parent Zarathustra <adam.chrapkowski gmail.com> writes:
Ok, more code :P beacuse problem is only with arrays.
class CPolygon3d{
  //______________________________________
  //  ::>> Attributes <<::
  //
 
  //______________________________________
  //  << fields >>
  //...
  private CPoint3d [] m_points;
  //...

  //______________________________________
  //  << properties >>
  //...

  // property getPoint
  //______________________________________
  public CPoint3d getPoint(){ return this.GetPoint; }

  // property getPoints
  //______________________________________
  public CPoint3d [] getPoints(){ return this.GetPoints; }

  //...
 
  //______________________________________
  //  ::>> Methods <<::
  //
   
  //...
 
  //______________________________________
  //  << operations >>

  //...

  // operation GetPoint
  //______________________________________
  private CPoint3d
  GetPoint()
  in{
    //...
  }
  out{
    //...
  }
  body{
    //...
  }

  // operation GetPoints
  //______________________________________
  private CPoint3d []
  GetPoints()
  in{
    //...
  }
  out{
    //...
  }
  body{
    //...
  }
}
 
class CPolygon2d : CPolygon3d{
  //______________________________________
  //  ::>> Attributes <<::
  //

  //______________________________________
  //  << fields >>
  //...
  private CPoint2d [] m_points;
  //...

  //______________________________________
  //  << properties >>
  //...

  // property getPoint
  //______________________________________
  public CPoint2d getPoint(){ return this.GetPoint; }  // ok
 
  // property getPoints
  //______________________________________
  public CPoint2d [] getPoints(){ return this.GetPoints; } // problem

  //...

  //______________________________________
  //  ::>> Methods <<::
  //
  
  //...

  //______________________________________
  //  << operations >>

  //...

  // opeartion GetPoint
  //______________________________________
  private CPoint2d
  GetPoint()
  in{
    //...
  }
  out{
    //...
  }
  body{
    //...
  }

  // opeartion GetPoints
  //______________________________________
  private CPoint2d []
  GetPoints()
  in{
    //...
  }
  out{
    //...
  }
  body{
    //...
  }

}
Jul 24 2008
prev sibling parent reply Zarathustra <adam.chrapkowski gmail.com> writes:
Sorry, for the amount of posts, but below is full and most easy example program
which ilustrates problem ;)
________________________________________________________
// class CFoo
//_______________________________________________
class CFoo{
  //_____________________________________________
  //  ::>> Attributes <<::
  //

  //_____________________________________________
  //  << fields >>
  
  public real [] test(){ return [3.4, 4.5]; }
}

// class CBar
//_________________________________________________
class CBar : CFoo{
    //_____________________________________________
  //  ::>> Attributes <<::
  //

  //_____________________________________________
  //  << fields >>
  public uint [] test(){ return [9, 8, 7]; }
}

void
main(char [][] args){
}
________________________________________________________
Jul 24 2008
parent reply Zarathustra <adam.chrapkowski gmail.com> writes:
Koroskin Denis Wrote:

 On Thu, 24 Jul 2008 17:23:44 +0400, Zarathustra  
 <adam.chrapkowski gmail.com> wrote:
 
 Sorry, for the amount of posts, but below is full and most easy example  
 program which ilustrates problem ;)
 ________________________________________________________
 // class CFoo
 //_______________________________________________
 class CFoo{
   //_____________________________________________
   //  ::>> Attributes <<::
   //

   //_____________________________________________
   //  << fields >>
  public real [] test(){ return [3.4, 4.5]; }
 }

 // class CBar
 //_________________________________________________
 class CBar : CFoo{
     //_____________________________________________
   //  ::>> Attributes <<::
   //

   //_____________________________________________
   //  << fields >>
   public uint [] test(){ return [9, 8, 7]; }
 }

 void
 main(char [][] args){
 }
 ________________________________________________________

I'm sorry, but your example is incorrect. You can't cast uint[] to real[]. If you need that, write a function for the task. Compiler won't do this automatically. And yes, they are not covariant! :)

Of course ;) You have a right ;p I'm blind. Now I see that I tied do something like that: typeA function(typeX x){} typeB function(typeX x){} of cource compiler which function call ;p sorry my very very stiupid mistake.
Jul 25 2008
parent reply Sivo Schilling <sivo.schilling web.de> writes:
Zarathustra Wrote:

 Koroskin Denis Wrote:
 
 On Thu, 24 Jul 2008 17:23:44 +0400, Zarathustra  
 <adam.chrapkowski gmail.com> wrote:
 
 Sorry, for the amount of posts, but below is full and most easy example  
 program which ilustrates problem ;)
 ________________________________________________________
 // class CFoo
 //_______________________________________________
 class CFoo{
   //_____________________________________________
   //  ::>> Attributes <<::
   //

   //_____________________________________________
   //  << fields >>
  public real [] test(){ return [3.4, 4.5]; }
 }

 // class CBar
 //_________________________________________________
 class CBar : CFoo{
     //_____________________________________________
   //  ::>> Attributes <<::
   //

   //_____________________________________________
   //  << fields >>
   public uint [] test(){ return [9, 8, 7]; }
 }

 void
 main(char [][] args){
 }
 ________________________________________________________

I'm sorry, but your example is incorrect. You can't cast uint[] to real[]. If you need that, write a function for the task. Compiler won't do this automatically. And yes, they are not covariant! :)

Of course ;) You have a right ;p I'm blind. Now I see that I tied do something like that: typeA function(typeX x){} typeB function(typeX x){} of cource compiler which function call ;p sorry my very very stiupid mistake.

If you consider functions, e.g. not class members you're right, but this is not your point. You can achive your task if you make the test() member in CFoo final. That means CFoo.test is no longer virtual and therefore it is not necessary to have a covariant return type for CBar.test. Your example above with the main function containing a simple test scenario compiles and runs with both DMD 1.033 and DMD 2.017 quite well: --- import std.stdio; // class CFoo //_______________________________________________ class CFoo{ //_____________________________________________ // ::>> Attributes <<:: // //_____________________________________________ // << fields >> // public real [] test(){ return [3.4, 4.5]; } final public real [] test(){ return [3.4, 4.5]; } } // class CBar //_________________________________________________ class CBar : CFoo{ //_____________________________________________ // ::>> Attributes <<:: // //_____________________________________________ // << fields >> public uint [] test(){ return [9, 8, 7]; } } void main(char [][] args){ CFoo foo = new CFoo; CBar bar = new CBar; writefln("foo.test() gives %s as expected.", foo.test); writefln("bar.test() gives %s as expected.", bar.test); } ---
Jul 26 2008
parent Zarathustra <adam.chrapkowski gmail.com> writes:
Sivo Schilling Wrote:

 Zarathustra Wrote:
 
 Koroskin Denis Wrote:
 
 On Thu, 24 Jul 2008 17:23:44 +0400, Zarathustra  
 <adam.chrapkowski gmail.com> wrote:
 
 Sorry, for the amount of posts, but below is full and most easy example  
 program which ilustrates problem ;)
 ________________________________________________________
 // class CFoo
 //_______________________________________________
 class CFoo{
   //_____________________________________________
   //  ::>> Attributes <<::
   //

   //_____________________________________________
   //  << fields >>
  public real [] test(){ return [3.4, 4.5]; }
 }

 // class CBar
 //_________________________________________________
 class CBar : CFoo{
     //_____________________________________________
   //  ::>> Attributes <<::
   //

   //_____________________________________________
   //  << fields >>
   public uint [] test(){ return [9, 8, 7]; }
 }

 void
 main(char [][] args){
 }
 ________________________________________________________

I'm sorry, but your example is incorrect. You can't cast uint[] to real[]. If you need that, write a function for the task. Compiler won't do this automatically. And yes, they are not covariant! :)

Of course ;) You have a right ;p I'm blind. Now I see that I tied do something like that: typeA function(typeX x){} typeB function(typeX x){} of cource compiler which function call ;p sorry my very very stiupid mistake.

If you consider functions, e.g. not class members you're right, but this is not your point. You can achive your task if you make the test() member in CFoo final. That means CFoo.test is no longer virtual and therefore it is not necessary to have a covariant return type for CBar.test. Your example above with the main function containing a simple test scenario compiles and runs with both DMD 1.033 and DMD 2.017 quite well: --- import std.stdio; // class CFoo //_______________________________________________ class CFoo{ //_____________________________________________ // ::>> Attributes <<:: // //_____________________________________________ // << fields >> // public real [] test(){ return [3.4, 4.5]; } final public real [] test(){ return [3.4, 4.5]; } } // class CBar //_________________________________________________ class CBar : CFoo{ //_____________________________________________ // ::>> Attributes <<:: // //_____________________________________________ // << fields >> public uint [] test(){ return [9, 8, 7]; } } void main(char [][] args){ CFoo foo = new CFoo; CBar bar = new CBar; writefln("foo.test() gives %s as expected.", foo.test); writefln("bar.test() gives %s as expected.", bar.test); } ---

Great, thanks! It's exactly that what I need. all regards
Jul 26 2008
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Zarathustra" wrote
 Steven Schveighoffer Wrote:

 "Zarathustra" wrote
 Steven Schveighoffer Wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides 
 but
 is
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns type CPoint3d[], but the derived class is returning CPoint2d[]. In order for this to work, CPoint2d[] must be implicitly castable to CPoint3d[], which probably isn't true. In order to diagnose the problem exactly, we would have to see code. At least the class hierarchy. -Steve

Ok, thanks. I understand it now. CPoint2d class is inherited by CPoint3d. Both classes have same named functions with this difference that one return CPoint2d object and second CPoin3d object. Is possible to extort to call correct function (not from parent class). It's strange, because CPoint2d can be casted to CPoint3d but not inversely.

I'm not quite sure how to interpret your statement. It might be better to understand by showing some stub code. Fill in where you see ???: class CPoint2d : ??? { } class CPoint3d : ??? { } class CPolygon2d : ??? { ???[] getPoints() {} } class CPolygon3d : ??? { ???[] getPoints() {} } -Steve

class CPoint3d{ } class CPoint2d : CPoint3d{ } class CPolygon3d{ CPoint3d [] getPoints() {} } class CPolygon2d : CPolygon3d{ CPoint2d [] getPoints() {} }

If this does not work, then I would say it is a bug. You should file it with this example code, fill in the function bodies, and paste the errors that result from it. -Steve
Jul 24 2008
prev sibling next sibling parent "Koroskin Denis" <2korden gmail.com> writes:
On Wed, 23 Jul 2008 21:37:22 +0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 "Lars Ivar Igesund" wrote
 Steven Schveighoffer wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides but
 is
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns type CPoint3d[], but the derived class is returning CPoint2d[]. In order for this to work, CPoint2d[] must be implicitly castable to CPoint3d[], which probably isn't true. In order to diagnose the problem exactly, we would have to see code. At least the class hierarchy. -Steve

Arrays are not implicitly castable (not even explicitly afaik) to another type, no matter how they are related.

From http://www.digitalmars.com/d/1.0/arrays.html A dynamic array T[] can be implicitly converted to one of the following: a.. U[] b.. void[] Where U is a base class of T. -Steve

It should be castable to *const(U)[]* but not to U[], it's a bug otherwise: class U { } class T : U { void foo() {} } void main() { T[] t = new T[42]; U[] u = t; u[0] = new U; t[0].foo(); // access violation } const(U)[] would prevent that.
Jul 23 2008
prev sibling next sibling parent "Koroskin Denis" <2korden gmail.com> writes:
On Wed, 23 Jul 2008 21:54:14 +0400, Lars Ivar Igesund  
<larsivar igesund.net> wrote:

 Steven Schveighoffer wrote:

 "Lars Ivar Igesund" wrote
 Steven Schveighoffer wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides  
 but
 is
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns type CPoint3d[], but the derived class is returning CPoint2d[]. In order for this to work, CPoint2d[] must be implicitly castable to CPoint3d[], which probably isn't true. In order to diagnose the problem exactly, we would have to see code. At least the class hierarchy. -Steve

Arrays are not implicitly castable (not even explicitly afaik) to another type, no matter how they are related.

From http://www.digitalmars.com/d/1.0/arrays.html A dynamic array T[] can be implicitly converted to one of the following: a.. U[] b.. void[] Where U is a base class of T.

Hmm, was it always that way? In any case, implicitly casting from U[] to T[] doesn't work, and if you do it explicitly, the result won't work (and IIRC doing foreach and cast was not an acceptable general solution), and as such T[] is not co-variant return type for U[].

No, whereas downcasting (obviously) doens't work, upcasting does. Just check my example that I posted earlier in this thread.
Jul 23 2008
prev sibling next sibling parent "Koroskin Denis" <2korden gmail.com> writes:
On Thu, 24 Jul 2008 15:19:59 +0400, Zarathustra  
<adam.chrapkowski gmail.com> wrote:

 Steven Schveighoffer Wrote:

 "Zarathustra" wrote
 Steven Schveighoffer Wrote:

 "Zarathustra" wrote
 error:
 function basis.CPolygon2d.getPoints of type CPoint2d[]() overrides  



 is
 not covariant with basis.CPolygon3d.getPoints of type CPoint3d[]()

 I don't know how to fix this problem. What does 'covariant' mean?

Covariant means that the override returns something that can be implicitly casted to the base version. So the error looks like the base class function getPoints returns


 CPoint3d[], but the derived class is returning CPoint2d[].  In order  


 this to work, CPoint2d[] must be implicitly castable to CPoint3d[],  


 probably isn't true.

 In order to diagnose the problem exactly, we would have to see  


 least the class hierarchy.

 -Steve

Ok, thanks. I understand it now. CPoint2d class is inherited by CPoint3d. Both classes have same named functions with this difference that one return CPoint2d object and

 CPoin3d object. Is possible to extort to call correct function (not  

 parent class). It's strange, because CPoint2d can be casted to  

 but not inversely.

I'm not quite sure how to interpret your statement. It might be better to understand by showing some stub code. Fill in where you see ???: class CPoint2d : ??? { } class CPoint3d : ??? { } class CPolygon2d : ??? { ???[] getPoints() {} } class CPolygon3d : ??? { ???[] getPoints() {} } -Steve

class CPoint3d{ } class CPoint2d : CPoint3d{ } class CPolygon3d{ CPoint3d [] getPoints() {} } class CPolygon2d : CPolygon3d{ CPoint2d [] getPoints() {} }

Well, it *should* work based on current semantics, because CPoint2d[] implicitly castable to CPoint3d[]. Moreover, it compiles with D2 but doesn't with D1. However, it is error-prone (as I showed previously) and is therefore better to avoid. Besides, it's an arguable design to inherit CPoint2d from CPoint3d :)
Jul 24 2008
prev sibling parent "Koroskin Denis" <2korden gmail.com> writes:
On Thu, 24 Jul 2008 17:23:44 +0400, Zarathustra  
<adam.chrapkowski gmail.com> wrote:

 Sorry, for the amount of posts, but below is full and most easy example  
 program which ilustrates problem ;)
 ________________________________________________________
 // class CFoo
 //_______________________________________________
 class CFoo{
   //_____________________________________________
   //  ::>> Attributes <<::
   //

   //_____________________________________________
   //  << fields >>
  public real [] test(){ return [3.4, 4.5]; }
 }

 // class CBar
 //_________________________________________________
 class CBar : CFoo{
     //_____________________________________________
   //  ::>> Attributes <<::
   //

   //_____________________________________________
   //  << fields >>
   public uint [] test(){ return [9, 8, 7]; }
 }

 void
 main(char [][] args){
 }
 ________________________________________________________

I'm sorry, but your example is incorrect. You can't cast uint[] to real[]. If you need that, write a function for the task. Compiler won't do this automatically. And yes, they are not covariant! :)
Jul 24 2008