With the exception of value-lists, explained below, the weight of a conversion path is considered to be the sum of the weights of all conversions along it. No more than one CONV_USER is allowed on a conversion path.
XParam will always choose the lightest available conversion path. If no conversion path can be considered lightest (for example, if two conversion paths are exactly as good) then XParam will call this an ambiguity.
This is more or less how C++ evaluates conversions, too. The main difference is that, in XParam, all conversions between type char and other built-in C++ types (numeric types) must be specified explicitly.
Because XParam works most commonly from the command-line, a more relaxed syntax is allowed in XParam to minimize the necessity of using characters that have meaning in Unix shell-parsing, such as quotations and apostrophes. For this reason, an assignment such as this:
my_parameter = 7
can be interpretted with the character 7 representing an explicit literal constant of type int, char or even std::string. XParam resolves this ambiguity by use of "tentative types" and destination-driven type matching. In essence, what this means is that XParam checks what types of explicit literal constants are permitted in the given context (for example, by checking the type of my_parameter) and then what types the given literal matches (in this case: int,char and std::string). Of the remaining options, XParam chooses according to the following rules:
When choosing between "func(int,int)" and "func(long,long)" when receiving an input, for example "func(3,5L)", C++ weighs each element separately, so the distance from "func(3,5L)" to "func(int,int)" is (CONV_EXACT, CONV_STANDARD), and the distance from "func(3,5L)" to "func(long,long)" is (CONV_STANDARD, CONV_EXACT). Now, we must determine which of these possibilities is better. The way to do it is to go element by element and compare. If one option is at-least as good as any other option in all elements, and better than all other options in at least one element, then it is considered the best. If two options are exactly as good in all elements, then the two options are considered to be as good, as a whole. If, on the other hand, as is the case here, when comparing two options there is an element that is better in one and another element that is better in the other, then the two options are considered incomparable. If asked to choose between them, both C++ and XParam will determine that this is an ambiguity.
XParam takes this element-by-element approach in lists, as well. If school, for example, is a class that can be constructed from a vector of integers or from a vector of fish, and the initialization line is "elementary=[ 4L, 5L ]", where "elementary" is a variable of type school, then XParam must now choose between converting "[4L, 5L]", element by element, into a list of integers, "[4, 5]", which can be converted into an std::vector<int>, and converting the "[4L, 5L]", element-by-element, into a list of fish, "[fish(4L), fish(5L)]", and from there to a std::vector<fish>.
Supposing class fish has a constructor from long, then the first option weighs (CONV_STANDARD, CONV_STANDARD) and the second option weighs (CONV_USER, CONV_USER). Therefore, XParam will choose going through a vector of integers.
Let's, however, make this example more complicated. What if "elementary" was not of type school but of type school*, and school was a parent class to public_school*, and, furthermore, that it is not school that has a constructor from a vector of integers but public_school?
If we sort through all the details, we'll find that XParam must now choose between two paths:
untyped list -> list of fish -> std::vector<fish> -> school
untyped list -> list of int -> std::vector<int> -> public_school -> school
We know that it is easier to go from our list to a vector of integers than it is to go to a vector of fish. However, once we get there, it weighs more to go from integers to school* than it is from fish to school*. Which will XParam choose? The rule is that any conversions that are done after an HVL-to-class conversion bare a negligent weight compared to what is done prior to the conversion. So, in this case, XParam will still decide to go through std::vector<int>. If the two conversions, until the switch from HVL to vector, had been uncomparable, then the entire paths would have been uncomparable. Only if the two conversion paths had been of equivalent weights until the switch from HVL to vector, the weights of the latter part of the conversion path would have had effect.
Previous: Frequently Asked Questions
Up: Table of Contents