[英]Why is the 'explicit' keyword allowing implicit conversions?
class Test {
private:
int value;
public:
void display(void)
{
cout << "Value [" << value << "]" << endl;
}
explicit Test(int i)
{
value=i;
}
};
int main() {
Test a(5);
Test b(4.9);
a.display();
b.display();
cin.get();
return 0;
}
即使提到了显式,浮点值也会转换为 int。
我期望(错误地) float 不会转换为 integer 和 object b 不会被构造。
explicit
不会阻止构造函数参数的隐式转换。 这意味着构造函数本身可能不被用作隐式转换到类类型Test
。
void func( Test ); // function declaration
func( 5 ); // Your "explicit" makes this call an error.
要防止构造函数(或任何函数)的参数的隐式转换,您可以使用C ++ 11 = delete
语法。
Test(int i)
{
value=i;
}
template<typename T>
Test(const T&) = delete;
// ^ Aside from your int constructor and the implicitly-generated
// copy constructor, this will be a better match for any other type
explicit
只是阻止任何隐式转换。 所以如果你有:
void foo(Test t);
你不能叫foo(4);
因为Test
构造函数是explicit
。 你必须打电话给foo(Test(4));
。 explicit
关键字与在构造期间可能必须发生的任何转换无关。
从标准[class.conv.ctor]:
显式构造函数与非显式构造函数一样构造对象,但仅在显式使用直接初始化语法(8.5)或强制转换(5.2.9,5.4)的情况下才这样做。
这意味着Test t = 4;
也是非法的,但Test t(42.0)
。
这是一个浮点积分转换。
也就是说:它是double
类型的纯右值到signed int
类型的纯右值之间的隐式转换。 它丢弃小数部分。
TL;DR:转换发生在“double”和“int”之间,而不是在您的Test
构造函数中。 如果您想阻止使用float
或double
调用该构造函数,您可以添加定义:
Test(double) = delete;
在您的Test
class 中。 生活在编译器资源管理器上
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.