[英]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.