Reputation: 681
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.
But still I can initialize A a1 = A(20.2);
. How can I disable the object creation such that an object can only be created if we pass an integer as a parameter e.g. A a1 = A(10)
?
#include <iostream>
class A
{
public:
explicit A(int a)
{
num = a;
}
int num;
};
int main()
{
A a1 = A(10.0);
std::cout << a1.num;
return 0;
}
Upvotes: 56
Views: 4864
Reputation: 47620
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;
}
Upvotes: 5
Reputation: 193
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.
Upvotes: 4
Reputation: 91
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
Upvotes: 9
Reputation: 2211
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);
}
Upvotes: 6
Reputation: 40080
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
Upvotes: 76
Reputation: 180595
The way to achieve this is to provide another constructor that would be a better match, and then delete
it so you'll get an error. For your class, adding
template <typename T>
A(T) = delete;
Will stop the class from being constructed from anything that isn't an int
Upvotes: 31
Reputation: 36483
Explicitly delete the constructor for double
(possibly add float
):
A(double) = delete;
Upvotes: 4