繁体   English   中英

为什么'explicit'关键字允许隐式转换?

[英]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构造函数中。 如果您想阻止使用floatdouble调用该构造函数,您可以添加定义:

Test(double) = delete;

在您的Test class 中。 生活在编译器资源管理器上

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM