I made the following custom long double class from C++'s long double. Then, the behavior of "echo 10" is 10, which is normal. But when I call "echo 10.uint" is "10.0000000". It seems that the converter will be called only for uint. Why such things occurs? I also noticed that when I import the following, it will be error becaus $ function is duplicated.
I intend to call converter only when I call directly such as "LongDouble(10)" and don't intend to call converter for "echo". Can I do such things?
type LongDouble* {.importcpp: "long double", nodecl .} = object
discard
proc initLongDouble*(a:SomeNumber):LongDouble {.importcpp: "(long double)(#)", nodecl.}
converter toLongDouble*(a:SomeInteger):LongDouble = initLongDouble(a.cint)
converter toLongDouble*(a:SomeFloat):LongDouble = initLongDouble(a.cdouble)
converter toLongDouble*(a:LongDouble):LongDouble = a
proc toCDouble*(a:LongDouble):cdouble {.importcpp: "(double)(#)", nodecl.}
converter toFloat*(a:LongDouble):float = toCDouble(a).float
converter toFloat64*(a:LongDouble):float64 = toCDouble(a).float64
converter toFloat32*(a:LongDouble):float32 = toCDouble(a).float32
proc init*(T:typedesc[LongDouble], a:SomeNumber):LongDouble = LongDouble(a)
proc getString*(a:LongDouble, s:var cstring) {.header:"<string>", importcpp: "(@) = std::to_string(#).c_str()", nodecl.}
proc `$`*(a:LongDouble):string =
var s:cstring
getString(a, s)
return $s
echo LongDouble(10) # 10.000000
echo LongDouble(10.uint) # 10.000000
echo 10 # 10
echo 10.uint # 10.000000
Beware of converters. They have their place, but should be used cautiously because they are very permissive.
In your particular case:
I would seriously consider not overriding SomeInteger and SomeFloat conversions. In fact, in this case, I recommend only having conversion from LongDouble, not the other way around. Have the toLongDouble variants be explicit procedures (proc) instead.
That or change the echo to:
echo (10.uint).int