[英]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;
}
Float value gets converted to int even though explicit is mentioned.即使提到了显式,浮点值也会转换为 int。
I was expecting (incorrectly) that float does not get converted to integer and object b not to be constructed.我期望(错误地) float 不会转换为 integer 和 object b 不会被构造。
explicit
does not prevent implicit conversions of constructor parameters . explicit
不会阻止构造函数参数的隐式转换。 It means that the constructor itself may not be used as an implicit conversion to your class type Test
. 这意味着构造函数本身可能不被用作隐式转换到类类型Test
。
void func( Test ); // function declaration
func( 5 ); // Your "explicit" makes this call an error.
To prevent implicit conversions of parameters for your constructor (or any function) you may use the C++11 = delete
syntax. 要防止构造函数(或任何函数)的参数的隐式转换,您可以使用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
just prevents any implicit conversions. explicit
只是阻止任何隐式转换。 So if you had: 所以如果你有:
void foo(Test t);
You cannot call foo(4);
你不能叫foo(4);
because the Test
constructor is explicit
. 因为Test
构造函数是explicit
。 You'd have to call foo(Test(4));
你必须打电话给foo(Test(4));
. 。 The explicit
keyword has nothing to do with any conversions that might have to happen during construction. explicit
关键字与在构造期间可能必须发生的任何转换无关。
From the standard [class.conv.ctor]: 从标准[class.conv.ctor]:
An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax (8.5) or where casts (5.2.9, 5.4) are explicitly used. 显式构造函数与非显式构造函数一样构造对象,但仅在显式使用直接初始化语法(8.5)或强制转换(5.2.9,5.4)的情况下才这样做。
Which means that Test t = 4;
这意味着Test t = 4;
is also illegal, but Test t(42.0)
is fine. 也是非法的,但Test t(42.0)
。
It's a Floating–integral conversion .这是一个浮点积分转换。
That is: it's an implicit conversion between a prvalue of type double
to a prvalue of type signed int
.也就是说:它是double
类型的纯右值到signed int
类型的纯右值之间的隐式转换。 It discards the fractional part.它丢弃小数部分。
TL;DR: the conversion happens between 'double' and 'int', not in your Test
constructor. TL;DR:转换发生在“double”和“int”之间,而不是在您的Test
构造函数中。 If you want to prevent that constructor to be called with a float
or a double
you can add the definition:如果您想阻止使用float
或double
调用该构造函数,您可以添加定义:
Test(double) = delete;
In your Test
class.在您的Test
class 中。 Live on compiler explorer 生活在编译器资源管理器上
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.