我能够避免使用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;
}
Run Code Online (Sandbox Code Playgroud)
YSC*_*YSC 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;
}
Run Code Online (Sandbox Code Playgroud)
演示:https : //coliru.stacked-crooked.com/a/425afc19003697c9
Nat*_*ica 30
实现此目的的方法是提供另一个匹配更好的构造函数,然后再构造delete
一个错误。对于您的班级,添加
template <typename T>
A(T) = delete;
Run Code Online (Sandbox Code Playgroud)
将阻止从任何非 int
小智 8
您可以通过使用大括号初始化来解决此问题。例如:
struct A {
A(int _a) : a(_a) {}
int a;
};
A a{5}; // ok
A b{1.123}; // compile error
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
为了避免在各处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;
}
Run Code Online (Sandbox Code Playgroud)