是编译器错误还是我在条件中使用 boost::tribool 时的错误

Is it compiler bug or my bug when using boost::tribool in a conditional?

本文关键字:错误 boost tribool 编译器 条件      更新时间:2023-10-16

代码如下:(科里鲁代码(

#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <boost/logic/tribool.hpp>
struct B
{
  boost::tribool boo;
  void bug ()
  {
    bool tmp = indeterminate (boo);
    std::cout << "tmp = " << std::boolalpha << tmp << "n";
    if (tmp && (boo = should_not_be_called ()) == false) {;}
  }
  bool should_not_be_called () const
  {
    std::cout << "BUG, wrong calln";
    abort ();
  }
};
int main ()
{
  B a;
  a.bug ();
}

输出为

tmp = false
BUG, wrong call
bash: line 7: 14410 Aborted                 (core dumped) ./a.out

我不明白为什么在这里叫should_not_be_called。测试的编译器是gcc 4.9和clang 3.6。

更新:

我阅读了答案并将带有"if"的行更改为

if (tmp && (false == (boo = should_not_be_called ()))) {;}

(科利鲁(

现在 && 运算符的两侧都有普通的布尔类型,但我仍然得到同样的错误。为什么?

编译器位于右侧。让我们分析一下您的两个if中涉及的类型,同时考虑到boost::tribool提供的所有运算符重载:

if (tmp && (boo = should_not_be_called ()) == false) {;}
if (bool && (tribool = bool) == bool) {;} // = is overloaded to return tribool
if (bool && tribool == bool) {;} // == is overloaded to return tribool
if (bool && tribool) {;} // && is overloaded

第二if

if (tmp && (false == (boo = should_not_be_called ()))) {;}
if (bool && (bool == (tribool = bool))) {;} // = is overloaded to return tribool
if (bool && (bool == tribool)) {;} // == is overloaded to return tribool
if (bool && tribool) {;} // && is overloaded

在这两种情况下,我们最终都会得到 超载operator && .运算符重载是不尊重内置运算符的特殊调用行为的函数。即用户过载&&||短路,用户过载,不保证操作数求值顺序。所有三个操作数都以未指定的顺序计算其所有操作数,就像任何其他函数调用一样。

这就是为什么强烈建议不要重载&&||,,如果你想让它们的意思是"和"、"或"和"序列"之类的东西。


摘录问题

原文:

编译器位于右侧。 boost::tribool重载opeator !,这意味着&&的操作数类型是boolboost::triboolboost::tribool还会重载这些参数类型的operator &&,因此将调用此重载。

boost::tribool 中的逻辑运算符是重载的,如此处所述,因此与 C++ 的内置逻辑运算符不同,逻辑运算符的从左到右计算不应用,并且没有短路,因此操作数的计算仍然未指定。