I am able to avoid the implicit conversion of a constructor using the explicit
keyword. So now, conversions like A a1 = 10;
can be avoided.
To avoid int->double conversions everywhere, not only in your case. With g++ you can use -Wconversion -Werror
. Note that it'll be allowed in your particular case, because the compiler understands that 10.0 is literal, but it will fail compilation for:
class A
{
public:
explicit A(int a)
{
num = a;
}
int num;
};
int main()
{
double x = 10;
A a1 = A(x);
static_cast<void>(a1);
return 0;
}
Compiler explorer
You can circumvent this problem by using braced initialization. For example:
struct A {
A(int _a) : a(_a) {}
int a;
};
A a{5}; // ok
A b{1.123}; // compile error
Proof
Explicitly delete the constructor for double
(possibly add float
):
A(double) = delete;
You should use the -Wconversion flag of gcc, that will generate a warning when implicitly casting a float to an int. Add -Werror to transform this warning (all in fact) into an error.
You can delete
A::A(<anything not an int>);
:
struct A
{
explicit A(int a)
: num(a)
{}
template<class T>
A(T) = delete;
int num;
};
int main()
{
//A a1=A(10.0); // error: use of deleted function 'A::A(T) [with T = double]'
A a2 = A(10); // OK
(void) a2;
}
Demo: https://coliru.stacked-crooked.com/a/425afc19003697c9
I just want to add that the A(double) = delete
is a C++11
addition.
If for whatever reason you cannot use this relatively new construct, you can simply declare it as private as this:
class A{
public:
A(int);
private:
A(double);
}