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