在 C++ 中使用多个三元运算符调用时,不区分 bool 和 enum 类型重载的函数

Function overloaded by bool and enum type is not differentiated while called using multiple ternary operator in C++

尝试使用条件运算符调用重载函数时遇到一个有趣的问题(只是为了避免多个 if else 条件)

class VirtualGpio
{

    typedef enum
    {
      OUTPUT = 0xC7,
      INPUT ,
      DIRINVALID
    }GpioDirection;
    struct pinconfig
    {
      struct pinmap pin;
      GpioPolarity plrty;  
      bool IsPullupCfgValid;
      bool IsTriStCfgValid;
      bool IsInputFilterValid;
      GpioDirection dic; 
      gpiolistner fptr;     // Callback function pointer on event change
    };

};

class factory
{

  public:

    VirtualGpio *GetGpiofactory(VirtualGpio::pinconfig *cfg,VirtualGpio::GpioAccessTyp acc=VirtualGpio::Pin);

  private:

      int setCfgSetting(VirtualGpio::pinmap * const getpin, VirtualGpio::GpioDirection const data);

      int setCfgSetting(VirtualGpio::pinmap * const getpin, bool const data);

};

int factory::setCfgSetting(VirtualGpio::pinmap * const getpin, VirtualGpio::GpioDirection const data)
{

  cout << "It is a Direction overloaded" << endl;

}

int factory::setCfgSetting(VirtualGpio::pinmap * const getpin, bool const data)
{

   cout << "It is a bool overloaded" << endl;

}

VirtualGpio* factory::GetGpiofactory(VirtualGpio::pinconfig *cfg,VirtualGpio::GpioAccessTyp acc)
{

  VirtualGpio * io = new VirtualGpio();

  printf("acc : 0x%X, pin : 0x%x, port : 0x%x\n",acc, cfg->pin.pinno, cfg->pin.portno);

  printf("value of expression : 0x%x\n",((acc == VirtualGpio::Pin)? cfg->dic : ((cfg->dic == VirtualGpio::INPUT)?true :false))); <= this prints the right value

  if(acc == VirtualGpio::Pin)

      setCfgSetting(&cfg->pin,cfg->dic);

  else if(cfg->dic == VirtualGpio::INPUT)

      setCfgSetting(&cfg->pin,true);

  else

      setCfgSetting(&cfg->pin,false);

#if 0
  if(setCfgSetting(&cfg->pin, ((acc == VirtualGpio::Pin)? cfg->dic : ((cfg->dic == VirtualGpio::INPUT)?true :false))) == ERROR)
   {

      printf("Error Setting the IO configuration for XRA\n");

   }

   else

    printf("Set IO config successfully\n");

#endif

  return io;

}

GetGpiofactory()中的注释部分#if 0同上 多个 if-else-if-else 块,但是如果我取消注释 #if0 部分到 #if 1、对于所有可能的输入只有bool版本的重载 函数即 setCfgSetting(VirtualGpio::pinmap * const getpin, bool const data) 被调用。

下面是我的主要代码。

main()
{

  static struct VirtualGpio::pinconfig cfg = {

    .pin = {
      .location = VirtualGpio::GPIO_ON_GPIOEXP1_TCI,
      .pinno = 0,
      .portno = -1
    },
    .plrty = VirtualGpio::active_high,
    .IsPullupCfgValid = true,
    .IsTriStCfgValid = true,
    .IsInputFilterValid = true,
    .dic = VirtualGpio::OUTPUT,
    .fptr = NULL
  };

  factory fac;

  fac.GetGpiofactory(&cfg);

}

令人惊讶的是,如果我不使用三元运算符而是使用多个 if-else if-else 块,重载函数运行良好。很想知道原因。

那是因为三元运算符的计算结果总是单一类型。您不能使用此运算符 "return" 不同的类型。

当编译器遇到这样的表达式时,他会尝试弄清楚是否可以将整个事物简化为一种类型。如果那不可能,你会得到一个编译错误。

在您的情况下,有一个使用 bool 作为类型的有效选项。因为 cfg->dic 是一个 enum 类型,可以隐式转换为 bool。如果您使用 and enum class,您的代码将不再编译,向您显示您的实际问题是什么 (example)。

我也不太明白这种代码有什么好处。在我看来,它使代码更难阅读。如果您担心它们太多,您可以将 ifs 减少到一个:

if(acc == VirtualGpio::Pin)
  setCfgSetting(&cfg->pin,cfg->dic);
else
  setCfgSetting(&cfg->pin, cfg->dic == VirtualGpio::INPUT);