[英]C++11 explicit conversion operators/constructors in return statement
我有一個以下示例(布爾類型過於安全):
#include <cstdlib>
struct boolean_type
{
explicit
boolean_type(bool _value)
: value_(_value)
{ ; }
explicit
operator bool () const
{
return value_;
}
private :
bool value_;
};
struct A
{
A(int const _i)
: i_(_i)
{ ; }
boolean_type operator == (A const & _other) const
{
return (i_ == _other.i_);
}
private :
int i_;
};
bool t()
{
return A(0) == A(0);
}
int main()
{
return EXIT_SUCCESS;
}
眾所周知,這樣的代碼包含錯誤:“無法轉換'((((int)((const A *)this))-> A :: i_ )==(((int) other.A :: i ) )'從bool A::operator == (A const &) const
返回語句中從'bool'轉換為'boolean_type'“,而在bool t()
返回語句中“無法將'boolean_type'轉換為'bool'”。 但是這里有什么風險? 為什么兩種情況下都沒有顯式轉換? 為什么是隱式的? 實際上,在第二種情況下,我們明確指定了返回類型bool
和static_assert(std::is_same< bool, decltype(std::declval< int >() == std::declval< int >()) >::value, "!");
因此!
另外要說:
由於指定的障礙,我無法在用戶代碼中簡單地將bool
所有條目替換為我的超安全boolean_type
(它是嘲笑的對象 ),因為,例如,在boost::variant::operator ==
返回語句中使用以上構造,將其視為隱式轉換 。 類似的障礙也不是唯一的。
您有兩個隱式轉換。 一個在這里:
return (i_ == _other.i_);
還有另一個在這里:
return A(0) == A(0);
這些是隱式的,因為您沒有明確告訴編譯器您要將比較的結果分別轉換為boolean_type
和bool
。 不允許進行這些隱式轉換,因為您使boolean_type
的構造函數和轉換運算符boolean_type
explicit
-這就是explicit
關鍵字的重點。
您需要執行以下操作:
return static_cast<boolean_type>(i_ == _other.i_);
和:
return static_cast<bool>(A(0) == A(0));
使bool
轉換明確的典型原因是,在您不打算使用轉換的情況下,可能會使用該轉換。 例如,如果您具有名為b1
和b2
boolean_type
對象且具有非explicit
轉換,則可以執行以下操作:
b1 > 0
b1 == b2
這些可能不是布爾轉換運算符的預期用途。
為什么兩種情況下都沒有顯式轉換?
因為責任在你 ,程序員,如果您希望顯式轉換是明確的。
如果您允許隱式轉換,則在這種情況下可以使用。 但是,當您將operator bool
和boolean_type::boolean_type
為explicit
時,您不允許它們。
為什么是隱式的?
因為您沒有編寫轉換。 你必須:
boolean_type operator == (A const & _other) const
{
return boolean_type (i_ == _other.i_);
}
...和:
bool t()
{
return (bool) (A(0) == A(0));
}
但是這里有什么風險?
你告訴我們。 explicit
存在是為了告訴編譯器允許進行一些隱式轉換而存在風險。 因此,當您將這些功能標記為explicit
您對編譯器說的是:
好的,如果您允許從布爾型向boolean_operator的隱式轉換,反之亦然,則可能會發生一些不良情況。 因此,不允許這些隱式轉換。
您沒有告訴編譯器(或我們) 為什么這些隱式轉換很危險。 你只說他們是 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.