簡體   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