MLine *line = new MLine((double)x, y, x - length_x1, y - length_y1);
The reason why this doesn't work is because the types derived are:
MLine(double, int, double, double)
which is because of ...
Promotion
In operations with mixed operands, the operands might be converted to other types. For operations on floating point types vs. integer types, the integers are converted to floating types first:
float f; int i;
f + i;
f + i
is of type float
because before the addition takes place, i
is converted to float
.
This promotion leads to ...
Ambiguity
There is no exact match, and the overload candidates are ambiguous.
Technically (and simplified), the C++ compiler will either use an exact match, or selects the best match out of a set of overload candidates. The rules are non-trivial (one measure being the number of conversions required).
Let me derive some examples:
void foo (int) {}
int main () { foo(5.f); }
-> Works, because there is only one candidate and double can be implicitly converted to int.
#include <iostream>
void foo (int) { std::cout << "foo(int)\n"; }
void foo (float) { std::cout << "foo(float)\n"; }
int main () { foo(5.f); }
-> The second version is used, because it is an exact match.
#include <iostream>
void foo (int) { std::cout << "foo(int)\n"; }
void foo (float) { std::cout << "foo(float)\n"; }
int main () { foo(5.); }
-> Note: This time, we are passing a double
. It won't compile, because both overloads require a conversion, are not exact matches, therefore, the candidates are ambiguous.
It is the same with multiple parameters:
#include <iostream>
void foo (int,int) { std::cout << "foo(int,int)\n"; }
void foo (float,float) { std::cout << "foo(float,float)\n"; }
int main () {
foo(5.f, 5.f); // exact match with the (float,float) overload
foo (5, 5); // exact match with the (int,int) overload
foo (5, 5.f); // No exact match, and candidates are ambiguous
}