Implicit cast of int to a class

Matthias Walter walter at mail.math.uni-magdeburg.de
Sun Nov 4 05:57:23 PST 2007


Bill Baxter Wrote:

> torhu wrote:
> > Matthias Walter wrote:
> >> Hello,
> >>
> >> I have a class called mpz_class which in particular implements the 
> >> following:
> >>
> >> 1. this (int other) { ... }
> >> 2. opAssign (int other) { ... }
> >>
> >> I now want to write templated code with T = int, T = long and T = 
> >> mpz_class.
> >> My mpz_class should work and feel like the orginal integers, which 
> >> mostly works.
> >>
> >> I'd like to know, how I can coax my class to implicitely convert 
> >> integer literals to instances of it. There are 2 cases which don't 
> >> compile for me and one which is semantically wrong:
> >>
> >> // 1.
> >> void func (T) (T input = 0) // error:  cannot implicitly convert 
> >> expression (0) of type int to gmp.mpz.mpz_class
> 
> 
> For structs, I think this should work, but it doesn't.  I was going to 
> file a bug about it, but never got around to it.  In my particular case 
> I was trying to make an array-like struct, and got bitten by the fact 
> that I could use my opAssign to use "MyStruct foo=null" as a default 
> argument.   For classes, as torhu points out, there's no LHS object 
> allocated, so it's not going to work without some bigger change to the 
> language.
> 
> 
> > I don't think it's possible to use defaults args like this.  It seems 
> > that opAssign isn't used for default args.  You need to remove the 
> > default, overload the function, specialize the template, or redesign the 
> > whole thing.
> > 
> > 
> >> // 2. T a = 1; // I guess, a points to 0x1 now and not to a result of 
> >> mpz_class.this(1)
> > 
> > Even if it tried to call opAssign, there's no object allocated.  It 
> > would just crash.  You have to use 'new' somewhere.  Maybe it's better 
> > to use a struct with static opCall overloads, instead of a class?  A 
> > struct is a better fit if you want it to behave like ints and longs, for 
> > sure.
> 
> 
> 
> --bb

Okay, I found one solution for everything which at least works:

a function num (T) (int n), which returns n if T is a native integer or "new T (n)" if not.
This work's as follows:

| void func (T) (T input = num !(T) (0))
| {
|   // ...
| }
|
| T a = num !(T) (1); // is correctly initialized.
|
| func !(T) (); // works with default parameter 0
| func !(T) (num !(T) (2)); // works

This is ugly typing (at least for a library like GMP, where one likes to do things like with normal integers!), so the problem could be solved, if

int i = new int (1);

would be semantically equivalent to

int i = 1;

So no allocation should happen! Although this isn't very nice syntax, because the reader might think that there happens allocation, but it would make work with GMP much easier!

best regards
Matthias


More information about the Digitalmars-d-learn mailing list