Consider the following:
struct A {
A(float ) { }
A(int ) { }
};
int main() {
A{1.1}; // error: ambiguous
}
This fails to compi
Narrowing is something the compiler only knows about for built-in types. A user defined implicit conversion can't be marked as narrowing or not.
Narrowing conversions shouldn't be permitted to be implicit in the first place. (Unfortunately it was required for C compatibility. This has been somewhat corrected with {}
initialization prohibiting narrowing for built-in types.)
Given these, it makes sense that the overload rules don't bother to mention this special case. It might be an occasional convenience, but it's not all that valuable. IMO it's better in general to have fewer factors involved in overload resolution and to reject more things as ambiguous, forcing the programmer to resolve such things explicitly.
Also, double to float is a narrowing conversion when the double isn't a constant expression or if the double is too large.
#include
#include
int main() {
double d{1.1};
float f{d};
std::cout << std::setprecision(100) << d << " " << f << '\n';
}
This will normally produce an error:
main.cpp:7:13: error: non-constant-expression cannot be narrowed from type 'double' to 'float' in initializer list [-Wc++11-narrowing]
float f{d};
^