我能够避免使用explicit
关键字对构造函数进行隐式转换。因此,现在可以避免像A a1 = 10;
这样的转化。
但是我仍然可以初始化A a1 = A(20.2);
。如何禁用对象创建,以便仅在我们将整数作为参数传递时才能创建对象,例如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;
}
答案 0 :(得分:74)
您可以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;
}
答案 1 :(得分:30)
实现此目的的方法是提供另一个匹配更好的构造函数,然后delete
进行匹配,这样您会得到一个错误。为您的班级添加
template <typename T>
A(T) = delete;
将阻止从非int
答案 2 :(得分:8)
您可以通过使用大括号初始化来解决此问题。例如:
struct A {
A(int _a) : a(_a) {}
int a;
};
A a{5}; // ok
A b{1.123}; // compile error
答案 3 :(得分:6)
我只想补充一下,A(double) = delete
是C++11
的补充。
如果出于某种原因您不能使用此相对较新的构造,则可以将其声明为私有:
class A{
public:
A(int);
private:
A(double);
}
答案 4 :(得分:5)
为了避免在各处int-> double转换,不仅限于您的情况。使用g ++,您可以使用-Wconversion -Werror
。请注意,在您的特定情况下将允许使用该代码,因为编译器理解10.0是文字的,但是它将失败于以下情况的编译:
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;
}
答案 5 :(得分:4)
明确删除double
的构造函数(可能添加float
):
A(double) = delete;
答案 6 :(得分:4)
您应该使用gcc的-Wconversion标志,在将float隐式转换为int时将生成警告。 添加-Werror可以将此警告(实际上全部)转换为错误。