Jump to page: 1 2 3
Thread overview
Classes in D and C++
Mar 05, 2007
Andy Little
Mar 05, 2007
Lionello Lunesu
Mar 05, 2007
Bill Baxter
Mar 05, 2007
Lionello Lunesu
Mar 05, 2007
Sean Kelly
Mar 05, 2007
Frits van Bommel
Mar 05, 2007
Lionello Lunesu
Mar 05, 2007
Bill Baxter
Mar 05, 2007
Andy Little
Mar 05, 2007
BCS
Mar 05, 2007
Andy Little
Mar 05, 2007
Andy Little
Mar 05, 2007
Uno
Mar 05, 2007
Walter Bright
Mar 05, 2007
Daniel Keep
Mar 05, 2007
Max Samukha
Mar 05, 2007
Max Samukha
Mar 05, 2007
Kyle Furlong
Mar 05, 2007
Daniel Keep
Mar 05, 2007
Lionello Lunesu
Mar 05, 2007
Lionello Lunesu
Mar 05, 2007
Uno
Mar 05, 2007
Sean Kelly
March 05, 2007
Hi all,

I have been evaluating D over the last day in comparison to C++.

The template metaprogramming stuff is great and I think its a real improvement over C++.

Sadly though theshowstopper for me is user defined types ( classes). I was hoping that I could port my physical quantities library to D, but the killer is the difference between classes in D and C++.

In C++ it is possible to create classes that act pretty much like inbuilt types. I used this to good effect in my quan library.

Unfortunately in D although you can do:

class X{
	this( int n_in){...}
}

Its not possible it seems to do e.g this:

X  x(3);

rather you have to do:

X x = new X(3);



Following is a cut down example of useage of my C++ Quan library, which I hope shows why this requirement on class types is (though possible) highly impractical for what I wanted to do. The physical quanties here are all UDT's (e.g classes) rather than double typedefs FWIW and are compile time checked to conform to dimensional analysis rules.



I sincerely hope that this post is seen in the right spirit. I am not attempting to be a troll, but just trying to explain where I am at in relation to D, and just kind of disappointed right now that D doesnt allow the flexibility with classes that I have in C++. e.g create classes with constructors on the stack, arbitrary temporaries etc, which may be syntactic sugar to an extent but is IMO very useful and satisfying to code.


Of course I may have this all wrong ...?

regards
Andy Little

// C++ code. compute chord and angle of wind turbine blade sections // using my quan library

chord_omega RotorDialog::getChordOmega(quan::length::m const& r)const
{
    using quan::length;
    using quan::velocity;
    using quan::mass_flow;
    using quan::force;
    using quan::pow;
    using quan::constant;
    using quan::angle;

    length::m const tip_r = this->m_outer_dia / 2.0;
    if (r > tip_r){
        throw std::out_of_range("getChordOmega Input radius is out of range");
    }

    velocity::m_per_s const Vin_y  = this->m_vw;
    length::m const  dr = get_section_spacing();
    velocity::m_per_s const  Vout_y
    = Vin_y
    * ( (r < tip_r)
        ? 1.0
          -  ((2.0 / 3.0) * (1.0 - this->m_ellipticality)
            + (this->m_ellipticality * sqrt(1.0 - pow<2>(r / tip_r) )))
        : 1.0 - (2.0/3.0)*(1.0 - this->m_ellipticality) );
    velocity::m_per_s const  Vb_y = (Vin_y + Vout_y) / 2.0;
    mass_flow::kg_per_s const  air_mass_flow
    = Vb_y * 2 * constant::pi * r * m_rho_air * dr;
    force::N const Fb_y = air_mass_flow * (Vin_y - Vout_y) ;
    double const  cl = this->m_cl;
    double const  drag_coeff  = this->m_cd / cl;

    velocity::m_per_s const epsilon = 0.0001 * abs(Vin_y);
    velocity::m_per_s const Vin_x = Vin_y * this->m_tsr * (r / tip_r);
    velocity::m_per_s Vout_x(0);
    velocity::m_per_s oldVout_x(0);
    for (int i = 0 ;i < 1000 ; ++i){
        velocity::m_per_s const Vb_x = Vout_x / 2.0 + Vin_x;
        angle::rad const beta = atan2(Vb_y,Vb_x);
        double const cos_beta = quan::cos(beta);
        double const sin_beta = quan::sin(beta);
        force::N const Lift
        = Fb_y /(cos_beta + drag_coeff * sin_beta);
        force::N const Fb_x
        = Lift * (sin_beta - drag_coeff * cos_beta);
        oldVout_x = Vout_x;
        Vout_x = Fb_x / air_mass_flow;
        if (compare(Vout_x,oldVout_x,epsilon) == 0 ){
            length::m const chord
            = Lift
            / ( (quan::pow<2>(Vb_x) + quan::pow<2>(Vb_y) )
                * 0.5 * this->m_rho_air
                * cl * dr * this->m_numblades );
            return chord_omega(chord,beta );
        }
    }//fail
    return chord_omega(length::mm(0.0),angle::rad(0.0));
}

March 05, 2007
Andy Little wrote:
> Hi all,
> 
> I have been evaluating D over the last day in comparison to C++.
> 
> The template metaprogramming stuff is great and I think its
> a real improvement over C++.
> 
> Sadly though theshowstopper for me is user defined types
> ( classes). I was hoping that I could port my physical quantities
> library to D, but the killer is the difference between classes in
> D and C++.
> 
> In C++ it is possible to create classes that act pretty much like
> inbuilt types. I used this to good effect in my quan library.
> 
> Unfortunately in D although you can do:
> 
> class X{
> 	this( int n_in){...}
> }
> 
> Its not possible it seems to do e.g this:
> 
> X  x(3);
> 
> rather you have to do:
> 
> X x = new X(3);

Why don't you use "struct" instead? A struct can have functions, operator overloads, just no constructor/destructor/virtuals, but for simple types these shouldn't be needed. For custom types that behave as value types, you should be using a "struct" instead of a class.

Instead of a constructor, create a "static opCall". opCall is the overload for "(..)" so you can instantiate your type similar to C++:

struct SomeType {
  int member = 0;// default initializer here
  static SomeType opCall( int whatever ) {
    SomeType st;
    st.member = whatever;//custom initialize
    return st;
  }
  //...
}

SomeType st = 2;//construction

No need for constructors ;)

L.
March 05, 2007
Lionello Lunesu wrote:
> Andy Little wrote:
>> Hi all,
>>
>> I have been evaluating D over the last day in comparison to C++.
>>
>> The template metaprogramming stuff is great and I think its
>  > a real improvement over C++.
>>
>> Sadly though theshowstopper for me is user defined types
>  > ( classes). I was hoping that I could port my physical quantities
>  > library to D, but the killer is the difference between classes in
>  > D and C++.
>>
>> In C++ it is possible to create classes that act pretty much like
>  > inbuilt types. I used this to good effect in my quan library.
>>
>> Unfortunately in D although you can do:
>>
>> class X{
>>     this( int n_in){...}
>> }
>>
>> Its not possible it seems to do e.g this:
>>
>> X  x(3);
>>
>> rather you have to do:
>>
>> X x = new X(3);
> 
> Why don't you use "struct" instead? A struct can have functions, operator overloads, just no constructor/destructor/virtuals, but for simple types these shouldn't be needed. For custom types that behave as value types, you should be using a "struct" instead of a class.
> 
> Instead of a constructor, create a "static opCall". opCall is the overload for "(..)" so you can instantiate your type similar to C++:
> 
> struct SomeType {
>   int member = 0;// default initializer here
>   static SomeType opCall( int whatever ) {
>     SomeType st;
>     st.member = whatever;//custom initialize
>     return st;
>   }
>   //...
> }
> 
> SomeType st = 2;//construction
> 
> No need for constructors ;)
> 
> L.

I don't think that quite works as you wrote.
I think it needs to be
   SomeType st = SomeType(2);
or
   auto st = SomeType(2);

if you want to avoid repeating your repeat-avoiding self repeatedly.

--bb
March 05, 2007
Bill Baxter wrote:
> Lionello Lunesu wrote:
>> Andy Little wrote:
>>> Hi all,
>>>
>>> I have been evaluating D over the last day in comparison to C++.
>>>
>>> The template metaprogramming stuff is great and I think its
>>  > a real improvement over C++.
>>>
>>> Sadly though theshowstopper for me is user defined types
>>  > ( classes). I was hoping that I could port my physical quantities
>>  > library to D, but the killer is the difference between classes in
>>  > D and C++.
>>>
>>> In C++ it is possible to create classes that act pretty much like
>>  > inbuilt types. I used this to good effect in my quan library.
>>>
>>> Unfortunately in D although you can do:
>>>
>>> class X{
>>>     this( int n_in){...}
>>> }
>>>
>>> Its not possible it seems to do e.g this:
>>>
>>> X  x(3);
>>>
>>> rather you have to do:
>>>
>>> X x = new X(3);
>>
>> Why don't you use "struct" instead? A struct can have functions, operator overloads, just no constructor/destructor/virtuals, but for simple types these shouldn't be needed. For custom types that behave as value types, you should be using a "struct" instead of a class.
>>
>> Instead of a constructor, create a "static opCall". opCall is the overload for "(..)" so you can instantiate your type similar to C++:
>>
>> struct SomeType {
>>   int member = 0;// default initializer here
>>   static SomeType opCall( int whatever ) {
>>     SomeType st;
>>     st.member = whatever;//custom initialize
>>     return st;
>>   }
>>   //...
>> }
>>
>> SomeType st = 2;//construction
>>
>> No need for constructors ;)
>>
>> L.
> 
> I don't think that quite works as you wrote.
> I think it needs to be
>    SomeType st = SomeType(2);
> or
>    auto st = SomeType(2);
> 
> if you want to avoid repeating your repeat-avoiding self repeatedly.
> 
> --bb

Actually, I was surprised myself, but it did work. And come to think of it, I remember Walter mentioning that he made it work, but I can't seem to find any reference to this in the changelog...

L.
March 05, 2007
Bill Baxter wrote:
> Lionello Lunesu wrote:
>>
>> Instead of a constructor, create a "static opCall". opCall is the overload for "(..)" so you can instantiate your type similar to C++:
>>
>> struct SomeType {
>>   int member = 0;// default initializer here
>>   static SomeType opCall( int whatever ) {
>>     SomeType st;
>>     st.member = whatever;//custom initialize
>>     return st;
>>   }
>>   //...
>> }
>>
>> SomeType st = 2;//construction
>>
>> No need for constructors ;)
> 
> I don't think that quite works as you wrote.
> I think it needs to be
>    SomeType st = SomeType(2);
> or
>    auto st = SomeType(2);
> 
> if you want to avoid repeating your repeat-avoiding self repeatedly.

Actually, with a slight modification that compiles just fine:
---
struct SomeType {
  int member = 0;// default initializer here
  static SomeType opCall( int whatever ) {
    SomeType st;
    st.member = whatever;//custom initialize
    return st;
  }
  //...
}

void main() {
    SomeType st = 2;//construction
}
---
Static opCall isn't compile-time executable since it uses a struct :(, so the declaration must be in a function. (This is actually a pretty good argument to allow compile-time execution to work with structs, I think)

This has been allowed for a while now, see http://www.digitalmars.com/d/changelog2.html#new0177 :
---
# Casting a value v to a struct S is now rewritten as S(v).
# Initializing a struct S from a value v is now rewritten as S(v).
---
March 05, 2007
Frits van Bommel wrote:
> This has been allowed for a while now, see http://www.digitalmars.com/d/changelog2.html#new0177 :
> ---
> # Casting a value v to a struct S is now rewritten as S(v).
> # Initializing a struct S from a value v is now rewritten as S(v).
> ---

Ah you found it! I didn't know it was pre-1.0 :)

L.
March 05, 2007
> Its not possible it seems to do e.g this:
> 
> X  x(3);
> 
> rather you have to do:
> 
> X x = new X(3);

Yep, I don't like that syntax too. Everywhere news.. And although D has many great features such small things prevent me to switch to D.

March 05, 2007
Lionello Lunesu wrote:
> Frits van Bommel wrote:
>> This has been allowed for a while now, see http://www.digitalmars.com/d/changelog2.html#new0177 :
>> ---
>> # Casting a value v to a struct S is now rewritten as S(v).
>> # Initializing a struct S from a value v is now rewritten as S(v).
>> ---
> 
> Ah you found it! I didn't know it was pre-1.0 :)
> 
> L.

Ah, ok.  I do remember those vague lines in the changelog now.


--bb
March 05, 2007
Uno wrote:
>> Its not possible it seems to do e.g this:
>>
>> X  x(3);
>>
>> rather you have to do:
>>
>> X x = new X(3);
> 
> Yep, I don't like that syntax too. Everywhere news.. And although D has many great features such small things prevent me to switch to D.
> 

You can do:

	auto x = X(3);

and x will be put on the stack.
March 05, 2007

Walter Bright wrote:
> Uno wrote:
>>> Its not possible it seems to do e.g this:
>>>
>>> X  x(3);
>>>
>>> rather you have to do:
>>>
>>> X x = new X(3);
>>
>> Yep, I don't like that syntax too. Everywhere news.. And although D has many great features such small things prevent me to switch to D.
>>
> 
> You can do:
> 
>     auto x = X(3);
> 
> and x will be put on the stack.

Surely you mean

  scope x = X(3);

Or did scope get rolled back into the auto keyword again while I wasn't looking? >_<

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
« First   ‹ Prev
1 2 3