www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - infer type argument in classe constructor?

reply Puming <zhaopuming gmail.com> writes:
Hi,

I'm writing a generic class:

```d

struct Message { ... }

class Decoder(MsgSrc) {
}
```

When using it, I'd have to include the type of its argument:

```
void main() {
    Message[] src = ...;

    auto decoder = new Decoder!(Message[])(src);

    ...
}
```

Can it be inferred so that I only need to write?

```d
auto decoder = new Decoder(src); // you can infer the type from 
src.
```
Mar 29 2016
next sibling parent reply Simen Kjaeraas <simen.kjaras gmail.com> writes:
On Tuesday, 29 March 2016 at 10:13:28 UTC, Puming wrote:
 Hi,

 I'm writing a generic class:

 ```d

 struct Message { ... }

 class Decoder(MsgSrc) {
 }
 ```

 When using it, I'd have to include the type of its argument:

 ```
 void main() {
    Message[] src = ...;

    auto decoder = new Decoder!(Message[])(src);

    ...
 }
 ```

 Can it be inferred so that I only need to write?

 ```d
 auto decoder = new Decoder(src); // you can infer the type from 
 src.
 ```
Nope. To see why, consider a class like this: class A(T) { T data; this(int n) { } } void main() { auto a = new A(3); // What is T? } The common solution is a simple 'create' function: Decoder!T decoder(T)(T msg) { return new Decoder!T(msg); } -- Simen
Mar 29 2016
parent Puming <zhaopuming gmail.com> writes:
On Tuesday, 29 March 2016 at 10:29:46 UTC, Simen Kjaeraas wrote:
 On Tuesday, 29 March 2016 at 10:13:28 UTC, Puming wrote:
 Hi,

 I'm writing a generic class:

 ```d

 struct Message { ... }

 class Decoder(MsgSrc) {
 }
 ```

 When using it, I'd have to include the type of its argument:

 ```
 void main() {
    Message[] src = ...;

    auto decoder = new Decoder!(Message[])(src);

    ...
 }
 ```

 Can it be inferred so that I only need to write?

 ```d
 auto decoder = new Decoder(src); // you can infer the type 
 from src.
 ```
Nope. To see why, consider a class like this: class A(T) { T data; this(int n) { } } void main() { auto a = new A(3); // What is T? }
Sorry I don't see it. In this case, I don't see an ambiguity? `int n` and T are not connected, so invoking A(3) means you are only setting the argument n to 3, so T can not be infered, and the compiler could just complain 'generic type T is not provided'.
 The common solution is a simple 'create' function:

 Decoder!T decoder(T)(T msg) {
     return new Decoder!T(msg);
 }

 --
   Simen
Mar 29 2016
prev sibling parent Edwin van Leeuwen <edder tkwsping.nl> writes:
On Tuesday, 29 March 2016 at 10:13:28 UTC, Puming wrote:
 Hi,

 I'm writing a generic class:

 ```d

 struct Message { ... }

 class Decoder(MsgSrc) {
 }
 ```

 When using it, I'd have to include the type of its argument:

 ```
 void main() {
    Message[] src = ...;

    auto decoder = new Decoder!(Message[])(src);

    ...
 }
 ```

 Can it be inferred so that I only need to write?

 ```d
 auto decoder = new Decoder(src); // you can infer the type from 
 src.
 ```
You can't directly. This is (AFAIK) because this()() can also be templated, making it impossible to just derive. The common way in D to deal with this/work around it is to create a helper function that can infer it: ```D auto decoder(T)(T src) { return new Decoder!T(src); } auto dec = decoder(src) ``` This pattern is widely used in phobos (e.g. tuple and Tuple)
Mar 29 2016