class foo {
public:
explicit foo(int) { std::cout<<"int constructor"; }
};
int main() {
foo f(0.1);
return 0;
}
I thought explicit keyword was being used to prevent unwanted type conversions, but the above code still works and outputs "int constructor". Why? And how to prevent that in this case?
You're confusing some concepts here.
explicit
prevents implicit constructor calls, not constructor calls with implicit parameter type conversions.Unfortunately the solution is not straightforward. It's not quite newbie-friendly and may require some googling to understand.
You could expicitly delete the constructors for floating-point types:
foo(float) = delete;
and so on. Thenfoo f(0.1);
will cause 'use of deleted function' error. But you won't be able to dofoo f(1l)
either, the compiler will complain about 'ambiguous overloads'.The proper way is following:
It's similar to deleting overloads for each floating-point type (as described above), but due to SFINAE, the deleted overload won't be considered for non-floating-point types.