【问题标题】:How does the safe bool idiom bool_type (and the safe bool idiom) work?安全布尔成语 bool_type(和安全布尔成语)如何工作?
【发布时间】:2011-10-09 15:03:00
【问题描述】:

我被指出了“安全布尔成语”,在试图破译发生了什么之后(supplied on the site 的解释不足以让我理解它为什么起作用),我决定尝试将以下代码分开,并尝试尽可能简化它。该网站提供的代码如下:

class Testable {
    bool ok_;
    typedef void (Testable::*bool_type)() const;
    void this_type_does_not_support_comparisons() const {}
  public:
    explicit Testable(bool b=true):ok_(b) {}

    operator bool_type() const {
      return ok_==true ? 
        &Testable::this_type_does_not_support_comparisons : 0;
    }
  };

我决定分析“bool_type”的关键基础,因为这似乎是它的中心。给定以下行:

typedef void (Testable::*bool_type)() const;

可以(不是那么容易,由于括号)推断它是类型为 'void Testable::*' 的 typedef,其中 bool_type 表示。这可以通过进行以下修改和函数调用来进一步证明:

class Testable {
    bool ok_;
    typedef void (Testable::*bool_type)() const;
    void this_type_does_not_support_comparisons() const {}
  public:
    explicit Testable(bool b=true):ok_(b) {}

    bool_type Test; //Added this

    operator bool_type() const {
      return ok_==true ?
        &Testable::this_type_does_not_support_comparisons : 0;
    }
  };

int main()
{
    Testable Test;
    int A = Test.Test; //Compiler will give a conversion error, telling us what type .Test is in the process
}

它可以让我们看到 bool_type 是什么类型:

错误:初始化时无法将 'void (Testable::*)()const' 转换为 'int'

这表明它确实是一种 'void (Testable::*)'。

问题在这里突然出现:

如果我们修改如下函数:

    operator bool_type() const {
      return ok_==true ? 
        &Testable::this_type_does_not_support_comparisons : 0;
    }

然后把它变成:

    operator void Testable::* () const //Same as bool_type, right? 
    {
      return ok_==true ? 
        &Testable::this_type_does_not_support_comparisons : 0;
    }

它会产生以下投诉:

错误:“*”标记之前的预期标识符
错误:“”声明为返回函数的函数

我的问题是:

如果 'void (Testable::*) 确实是 bool_type 的 typedef,为什么会产生这些抱怨?

还有

这是怎么回事?

【问题讨论】:

  • 为什么一个人在标题中提出一个问题,然后在正文中提出一个完全不同的问题?更何况两个这么不同的问题?
  • 有什么问题? bool_type 是一个指向成员函数的指针,指向 void Testable::some_function() const 类型的函数。 “由于括号”没有混淆(尽管 C++ 声明语法并不完全是美的缩影)。
  • 我从来没有说过混淆这个词,我只是说不容易推断 (Testable::*bool_type) 乍一看似乎是一个指向名为 bool_type 的变量的指针。除非它不是,因为 typedef 意味着使用的最后一个词是 typedef 在它之前的所有内容之后。即使它被括号括起来(与优先级相反)。
  • @Alf Point 是,为什么替换 bool_type 不起作用?而且,我看不出它与标题有何不同(这里发生了什么?=安全的布尔成语如何工作?;为什么会产生这些抱怨= bool_type 是如何工作的)。我只是觉得你很迂腐。
  • @SSight3:标题问题是关于一种反模式(使用邪恶的隐式转换,同时使用类似 rube goldberg 的技术来避免一个特定的陷阱),而文本中的问题仅与 C++ 语法有关.

标签: c++ safe-bool-idiom


【解决方案1】:

你的推理在这里出错了

operator void Testable::* () const //Same as bool_type, right? 

这是不正确的。 bool_type 的类型,正如编译器在错误消息中告诉我们的那样:

'void (Testable::*)()const'

因此,要在运算符中替换它,您需要类似

operator (void (Testable::*)() const) () const

如果可能的话!明白为什么即使是丑陋的 typedef 也是一种改进?

在 C++11 中,我们还拥有新的构造 explicit operator bool() 来将我们从这种丑陋中拯救出来。

【讨论】:

  • 让我猜猜,显式使它仅适用于布尔值?聪明的主意。感谢您实际回答问题。
  • s/answering the question/making a really good guess at what the question was/
猜你喜欢
  • 2012-07-31
  • 1970-01-01
  • 2011-09-08
  • 2011-10-16
  • 1970-01-01
  • 2011-04-25
  • 2018-04-23
  • 1970-01-01
  • 2011-09-12
相关资源
最近更新 更多