I took advantage of the 'BUG : Illicit "error 202: Illegal member access, UDT.operator.cast" compiler error message' analysis to redo and complete all the conversion cases relating to UDTs.
I also updated and completed the below paragraph of the Coercion and Conversion (Variables and Datatypes) documentation page of the Programmer's Guide:
Conversions using User Data Type constructors and operators
- .....
.....
- For conversion between built-in types (among standard types like between numeric types as above or between string types), the compiler knows what to do without the need for instructions from user.
This is called the implicit internal conversion (or coercion).
When one of the two types is at least a UDT (User Defined Type), the user has to code some UDT procedures to define how do the conversion.
Then, the conversion execution can be explicit if the user specifies what UDT procedure must be used, or implicit if the user leaves the choice to compiler.
In the world of UDTs, conversions can be controlled by means of three member procedures:For a construction with implicit initialization ('Dim As UDT u = v'), the compiler searches by priority:
- - Single-argument constructor: allow conversion from a particular type to initialize an object.
- Assignment operator: allow conversion from a particular type on assignment.
- Type-cast operator: allow conversion to a particular type.For an implicit copy-construction ('Byval As u_type') when passing a v type parameter, the compiler searches by priority:
- - Firstly a matched constructor (for u type from v type).
- Secondly a cast operator (for v type to special type (*)) and its matching conversion-constructor (for u type from special type (*)).
- Thirdly finally a matched cast operator (for v type to u type).
(a matched let operator (for u type from v type) is not searched by compiler on a construction with implicit initialization)For an implicit assignment ('u = v'), or an implicit return from function by assigning ('Function = v') with function returning u type, the compiler searches by priority:
- - Firstly a matched cast operator (for v type to u type).
- Secondly a matched constructor (for u type from v type).
- Thirdly finally a cast operator (for v type to special type (*)) and its matching conversion-constructor (for u type from special type (*)).
(a matched let operator (for u type from v type) is not searched by compiler on a construction with implicit initialization)For an implicit return from function by exiting immediately ('Return v') with function returning u type, the compiler searches by priority:
- - Firstly a matched let operator (for u type from v type).
- Secondly a cast operator (for v type to special type (*)) and its matching let operator (for u type from special type (*)).
- Thirdly a matched cast operator (for v type to u type).
- Fourthly finally a matched constructor (for u type from v type) and an explicit copy-let operator (u type).special type (*) : pointer or string, or UDT if there is no explicit copy-constructor / explicit copy-assignment operator for u type
- - Firstly a matched constructor (for u type from v type).
- Secondly a cast operator (for v type to special type (*)) and its matching conversion-constructor (for u type from special type (*)).
If an explicit copy-constructor (u type) exists:
- Thirdly a matched cast operator (for v type to u type).
- Fourthly finally a matched let operator (for u type from v type).
Else (an explicit copy-constructor (u type) does not exist):
- Thirdly a matched let operator (for u type from v type).
- Fourthly finally a matched cast operator (for v type to u type).
Code to check the precedence list above:
This code allows to check the precedence of the constructors/operators for each conversion case (among the five) by commenting or not the #define lines only.
Code: Select all
'' This code allows to check the precedence of the constructors/operators
'' for each conversion case (among the five)
'' by commenting or not the #define lines only.
'' test cases selected:
#define dim_as_TU_from_TV
#define byval_as_TU_from_TV
#define equal_as_TU_from_TV
#define function_equal_from_TV_to_TU
#define return_from_TV_to_TU
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
#define TV_cast_to_TU
Type _TV As TV
Type TU
Dim As Integer I
#ifdef TU_ctor_from_TV
Declare Constructor(Byref v As _TV)
#endif
#ifdef TU_ctor_from_string
Declare Constructor(Byref s As String)
#endif
#ifdef TU_let_from_TV
Declare Operator Let(Byref v As _TV)
#endif
#ifdef TU_let_from_string
Declare Operator Let(Byref s As String)
#endif
Declare Constructor()
#ifdef TU_ctor_from_TU
Declare Constructor(Byref u As TU)
#endif
#ifdef TU_let_from_TU
Declare Operator Let(Byref u As TU)
#endif
End Type
Type TV
Dim As Integer I
#ifdef TV_cast_to_string
Declare Operator Cast() As String
#endif
#ifdef TV_cast_to_TU
Declare Operator Cast() As TU
#endif
End Type
Dim Shared As TU u0
Dim Shared As TV v
#ifdef TU_ctor_from_TV
Constructor TU(Byref v As TV)
Print " Constructor TU(Byref As TV)"
End Constructor
#endif
#ifdef TU_ctor_from_string
Constructor TU(Byref s As String)
Print " Constructor TU(Byref As String)"
End Constructor
#endif
#ifdef TU_let_from_TV
Operator TU.Let(Byref v As TV)
Print " Operator TU.Let(Byref As TV)"
End Operator
#endif
#ifdef TU_let_from_string
Operator TU.Let(Byref s As String)
Print " Operator TU.Let(Byref As String)"
End Operator
#endif
Constructor TU()
End Constructor
#ifdef TU_ctor_from_TU
Constructor TU(Byref u As TU)
Print " Constructor TU(Byref As TU)"
End Constructor
#endif
#ifdef TU_let_from_TU
Operator TU.Let(Byref u As TU)
Print " Operator TU.Let(Byref As TU)"
End Operator
#endif
#ifdef TV_cast_to_string
Operator TV.Cast() As String
Print " Operator TV.Cast() As String"
Return ""
End Operator
#endif
#ifdef TV_cast_to_TU
Operator TV.Cast() As TU
Print " Operator TV.Cast() As TU"
Return u0
End Operator
#endif
#ifdef dim_as_TU_from_TV
Print "'Dim As TU u = v':"
Dim As TU u = v
Print
#else
Dim As TU u
#endif
#ifdef byval_as_TU_from_TV
Sub s(Byval u As TU)
End Sub
Print "'Byval As TU' (from TV):"
s(v)
Print
#endif
#ifdef equal_as_TU_from_TV
Print "'u = v':"
u = v
Print
#endif
#ifdef function_equal_from_TV_to_TU
Function f1() As TU
Function = v
End function
Print "'Function = v' to TU:"
f1()
Print
#endif
#ifdef return_from_TV_to_TU
Function f2() As TU
Return v
End function
Print "'Return v' to TU:"
f2()
Print
#endif
Sleep
For the conversion case : 'Dim As TU u = v'
Code: Select all
'' test cases selected:
#define dim_as_TU_from_TV
'#define byval_as_TU_from_TV
'#define equal_as_TU_from_TV
'#define function_equal_from_TV_to_TU
'#define return_from_TV_to_TU
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Dim As TU u = v':
Constructor TU(Byref As TV)
Code: Select all
'' constructors/operators defined:
'#define TU_ctor_from_TV
#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Dim As TU u = v':
Operator TV.Cast() As String
Constructor TU(Byref As String)
Code: Select all
'' constructors/operators defined:
'#define TU_ctor_from_TV
'#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
'#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Dim As TU u = v':
Operator TV.Cast() As TU
Constructor TU(Byref As TU)
Constructor TU(Byref As TU)
For the conversion case : 'Byval As TU' (from TV)
Code: Select all
'' test cases selected:
'#define dim_as_TU_from_TV
#define byval_as_TU_from_TV
'#define equal_as_TU_from_TV
'#define function_equal_from_TV_to_TU
'#define return_from_TV_to_TU
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Byval As TU' (from TV):
Operator TV.Cast() As TU
Constructor TU(Byref As TU)
Constructor TU(Byref As TU)
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
'#define TV_cast_to_TU
Code: Select all
'Byval As TU' (from TV):
Constructor TU(Byref As TV)
Code: Select all
'' constructors/operators defined:
'#define TU_ctor_from_TV
#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
'#define TV_cast_to_TU
Code: Select all
'Byval As TU' (from TV):
Operator TV.Cast() As String
Constructor TU(Byref As String)
For the conversion case : 'u = v'
Code: Select all
'' test cases selected:
'#define dim_as_TU_from_TV
'#define byval_as_TU_from_TV
#define equal_as_TU_from_TV
'#define function_equal_from_TV_to_TU
'#define return_from_TV_to_TU
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'u = v':
Operator TU.Let(Byref As TV)
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
'#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'u = v':
Operator TV.Cast() As String
Operator TU.Let(Byref As String)
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
'#define TU_let_from_TV
'#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
'#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'u = v':
Operator TV.Cast() As TU
Constructor TU(Byref As TU)
Operator TU.Let(Byref As TU)
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
'#define TU_let_from_TV
'#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
'#define TV_cast_to_string
'#define TV_cast_to_TU
Code: Select all
'u = v':
Constructor TU(Byref As TV)
Operator TU.Let(Byref As TU)
For the conversion case : 'Function = v' to TU
Code: Select all
'' test cases selected:
'#define dim_as_TU_from_TV
'#define byval_as_TU_from_TV
'#define equal_as_TU_from_TV
#define function_equal_from_TV_to_TU
'#define return_from_TV_to_TU
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Function = v' to TU:
Operator TU.Let(Byref As TV)
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
'#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Function = v' to TU:
Operator TV.Cast() As String
Operator TU.Let(Byref As String)
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
'#define TU_let_from_TV
'#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
'#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Function = v' to TU:
Operator TV.Cast() As TU
Constructor TU(Byref As TU)
Operator TU.Let(Byref As TU)
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
'#define TU_let_from_TV
'#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
'#define TV_cast_to_string
'#define TV_cast_to_TU
Code: Select all
'Function = v' to TU:
Constructor TU(Byref As TV)
Operator TU.Let(Byref As TU)
For the conversion case : 'Return v' to TU
Code: Select all
'' test cases selected:
'#define dim_as_TU_from_TV
'#define byval_as_TU_from_TV
'#define equal_as_TU_from_TV
'#define function_equal_from_TV_to_TU
#define return_from_TV_to_TU
Code: Select all
'' constructors/operators defined:
#define TU_ctor_from_TV
#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Return v' to TU:
Constructor TU(Byref As TV)
Code: Select all
'' constructors/operators defined:
'#define TU_ctor_from_TV
#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Return v' to TU:
Operator TV.Cast() As String
Constructor TU(Byref As String)
Code: Select all
'' constructors/operators defined:
'#define TU_ctor_from_TV
'#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
'#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Return v' to TU:
Operator TV.Cast() As TU
Constructor TU(Byref As TU)
Constructor TU(Byref As TU)
Code: Select all
'' constructors/operators defined:
'#define TU_ctor_from_TV
'#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
#define TU_ctor_from_TU
#define TU_let_from_TU
'#define TV_cast_to_string
'#define TV_cast_to_TU
Code: Select all
'Return v' to TU:
Operator TU.Let(Byref As TV)
Code: Select all
'' constructors/operators defined:
'#define TU_ctor_from_TV
'#define TU_ctor_from_string
#define TU_let_from_TV
#define TU_let_from_string
'#define TU_ctor_from_TU
#define TU_let_from_TU
'#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Return v' to TU:
Operator TU.Let(Byref As TV)
Code: Select all
'' constructors/operators defined:
'#define TU_ctor_from_TV
'#define TU_ctor_from_string
'#define TU_let_from_TV
#define TU_let_from_string
'#define TU_ctor_from_TU
#define TU_let_from_TU
'#define TV_cast_to_string
#define TV_cast_to_TU
Code: Select all
'Return v' to TU:
Operator TV.Cast() As TU
Operator TU.Let(Byref As TU)