Thread overview
infer type argument in classe constructor?
Mar 29, 2016
Puming
Mar 29, 2016
Simen Kjaeraas
Mar 29, 2016
Puming
Mar 29, 2016
Edwin van Leeuwen
March 29, 2016
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.
```
March 29, 2016
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
March 29, 2016
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)
March 29, 2016
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