opCast / operator overloading with additional template arguments

Steven Schveighoffer schveiguy at gmail.com
Mon Jan 11 00:48:49 UTC 2021


On 1/10/21 7:09 PM, Paul wrote:
> Is there a way to have additional template arguments in operator overloads?
> The problem I'm having is mostly caused by casting a templated struct to 
> other templated structs. I had the following code;
> 
>> T opCast(T)() const if (is(T : Vec!(vecsize, S), S)) {
>>     T converted;
>>     static foreach (i; 0 .. vecsize)
>>         converted.content[i] = cast(S) content[i];
>>     return converted;
>> }
> 
> When I try to use this, I get the error 'undefined identifier S'.
> Alternatively using:
>> T opCast(T, S)() . . .
> causes the error 'template instance opCast!(Vec!(2, double)) does not 
> match template declaration opCast(T, S)()'
> 
> I found using 'alias S = typeof(content[0])' works as a kind of ducttape 
> alternative, however this seems like a codesmell to me, and I fear it 
> won't scale well either.
> 
> Am I missing a simple solution? And why is there no automatic argument 
> deduction in this scenario when compared to normal function calls? (if 
> the above opcast is translated to 'foo.opCast!T`)

It has nothing to do with operator overloads. types inferred inside 
template constraints are not accessible inside the function.

The awkward solution is to use the same is expression inside the function:

static if(is(T : Vec!(vecsize, S), S)) {}

// now you can use S

I would think though, that this should work:

T opCast(T : Vec!(vecsize, S), S)()

But I don't have your full code to test.

-Steve


More information about the Digitalmars-d-learn mailing list