0

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

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,为什么会产生这些抱怨?

这里发生了什么?

4

1 回答 1

3

你的推理在这里出错了

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

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

'无效(可测试::*)()常量'

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

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

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

在 C++11 中,我们也有新的构造explicit operator bool()来让我们摆脱这种丑陋。

于 2011-10-09T16:26:59.230 回答