简体   繁体   English

返回语句中的C ++ 11显式转换运算符/构造函数

[英]C++11 explicit conversion operators/constructors in return statement

I have a following example (with overly safe boolean type): 我有一个以下示例(布尔类型过于安全):

#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;
}

It is well-known that such code containing an errors: "could not convert '(((int)((const A*)this)->A::i_) == ((int) other.A::i ))' from 'bool' to 'boolean_type'" in return statement of bool A::operator == (A const &) const and "cannot convert 'boolean_type' to 'bool'" in return statement of bool t() . 众所周知,这样的代码包含错误:“无法转换'((((int)((const A *)this))-> A :: i_ )==(((int) other.A :: i ) )'从bool A::operator == (A const &) const返回语句中从'bool'转换为'boolean_type'“,而在bool t()返回语句中“无法将'boolean_type'转换为'bool'”。 But what the risk here? 但是这里有什么风险? Why there are not explicit conversion here in both cases? 为什么两种情况下都没有显式转换? Why are implicit? 为什么是隐式的? In fact we explicitly specify the returning type bool in second case and static_assert(std::is_same< bool, decltype(std::declval< int >() == std::declval< int >()) >::value, "!"); 实际上,在第二种情况下,我们明确指定了返回类型boolstatic_assert(std::is_same< bool, decltype(std::declval< int >() == std::declval< int >()) >::value, "!"); as such! 因此!

Additionally want to say: 另外要说:

Due to the specified obstruction I cannot simply replace all entries of the bool to my super-safe boolean_type (which is mocked-object ) in my user code, because, say, in return statement of boost::variant::operator == uses above construction, that treats there as implicit conversion . 由于指定的障碍,我无法在用户代码中简单地将bool所有条目替换为我的超安全boolean_type (它是嘲笑的对象 ),因为,例如,在boost::variant::operator ==返回语句中使用以上构造,将其视为隐式转换 Similar obstructions are not unique. 类似的障碍也不是唯一的。

You have two implicit conversions. 您有两个隐式转换。 One here: 一个在这里:

return (i_ == _other.i_);

And another here: 还有另一个在这里:

return A(0) == A(0);

These are implicit because you are not explicitly telling the compiler that you want to convert the result of the comparisons to boolean_type and bool respectively. 这些是隐式的,因为您没有明确告诉编译器您要将比较的结果分别转换为boolean_typebool These implicit conversions are not allowed because you made both the constructor and conversion operator of boolean_type explicit - that's the whole point of the explicit keyword. 不允许进行这些隐式转换,因为您使boolean_type的构造函数和转换运算符boolean_type explicit -这就是explicit关键字的重点。

You would need to do: 您需要执行以下操作:

return static_cast<boolean_type>(i_ == _other.i_);

And: 和:

return static_cast<bool>(A(0) == A(0));

The typical reason for making conversions to bool explicit is because the conversion may be used in situations that you did not intend it to be used. 使bool转换明确的典型原因是,在您不打算使用转换的情况下,可能会使用该转换。 For example, if you had boolean_type objects called b1 and b2 with non- explicit conversions, you would be able to do the following: 例如,如果您具有名为b1b2 boolean_type对象且具有非explicit转换,则可以执行以下操作:

b1 > 0
b1 == b2

These are probably not the intended uses of the boolean conversion operator. 这些可能不是布尔转换运算符的预期用途。

Why there are not explicit conversion here in both cases? 为什么两种情况下都没有显式转换?

Because the onus is on you , the programmer, to be explicit if you want an explicit conversion. 因为责任在 ,程序员,如果您希望显式转换是明确的。

Implicit conversions would work in this case if you had allowed them. 如果您允许隐式转换,则在这种情况下可以使用。 But you didn't allow them when you marked operator bool and boolean_type::boolean_type as explicit . 但是,当您将operator boolboolean_type::boolean_typeexplicit时,您不允许它们。

Why are implicit? 为什么是隐式的?

Because you did not write the conversion. 因为您没有编写转换。 You must: 你必须:

  boolean_type operator == (A const & _other) const
  {   
      return boolean_type (i_ == _other.i_);
  }

...and: ...和:

bool t()
{   
    return (bool) (A(0) == A(0));
}

But what the risk here? 但是这里有什么风险?

You tell us. 你告诉我们。 explicit exists specifically to tell the compiler that there might be a risk in permitting some implicit conversions to take place. explicit存在是为了告诉编译器允许进行一些隐式转换而存在风险。 So when you marked those functions as explicit you said to the compiler: 因此,当您将这些功能标记为explicit您对编译器说的是:

Ok, if you allow an implicit conversion from a bool to a boolean_operator or vice versa, something bad might happen. 好的,如果您允许从布尔型向boolean_operator的隐式转换,反之亦然,则可能会发生一些不良情况。 So don't allow those implicit conversions. 因此,不允许这些隐式转换。

You didn't tell the compiler (or us) why those implicit conversions are dangerous. 您没有告诉编译器(或我们) 为什么这些隐式转换很危险。 You only said that they were . 你只说他们

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

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