I have a type defined in C# like this:
struct F {
public static explicit operator F(long value) {}
public static explicit operator long(F value) {}
public static explicit operator F(double value) {}
public static explicit operator double(F value) {}
// more conversion operators
}
In F# if I want to create it from a long, the only way I found is:
let l = F.op_Explicit 3L
I tried creating an inline function to make this nicer:
let inline f a = F.op_Explicit a
But this doesn't compile. I also tried with a member constraint:
let inline f (x:^a) = (F: (static member op_Explicit : ^a -> F) x)
And that doesn't compile either.
Is it possible to define a function or operator to choose the right overload?
On a side note, it does work nicely in the opposite direction:
let f = someF |> int64 // calls the right conversion operator
The operator overloading defines a type conversion operator that can be used to produce an int type from a Counter object. This operator will be used whenever an implicit or explict conversion of a Counter object to an int is required. Notice that constructors also play a role in type conversion.
To overload the function that casts our class to an int, we write a new function in our class called operator int(). Note that there is a space between the word operator and the type we are casting to. User-defined conversions do not take parameters, as there is no way to pass arguments to them.
Yes, there is something called implicit operator overloading. According to MSDN, an implicit keyword is used to declare an implicit user-defined type conversion operator. In other words, this gives the power to your C# class, which can accepts any reasonably convertible data type without type casting.
Operator Overloading in C++ This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading. For example, we can overload an operator '+' in a class like String so that we can concatenate two strings by just using +.
It's not valid to have a member constraint on a single concrete type; however, this might work for you:
let inline f (x:^a) : F =
let inline g x = ((^b or ^c):(static member op_Explicit : ^b -> ^c) x)
g x
This has the more general type f : ^a -> F when ( ^a or F) : (static member op_Explicit : ^a -> F)
, which is a type that is impossible to manually annotate any value with!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With