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

时间:2017-12-15 08:50:07

标签: c++ ternary-operator overloading

尝试使用条件运算符调用重载函数时遇到了一个有趣的问题(只是为了避免多个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;

}

#if 0中的评论部分GetGpiofactory()与上述内容相同  多个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块,则重载函数效果很好。很想知道原因。

1 个答案:

答案 0 :(得分:0)

这是因为三元运算符总是评估为单一类型。您不能使用此运算符“返回”不同的类型。

当编译器遇到这样的表达式时,他试图弄清楚他是否可以将整个事物减少到一种类型。如果这不可能,则会出现编译错误。

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

此外,我还没有看到这种代码的优点是什么。在我看来,它使代码更难阅读。如果你担心他们太多,你可以将ifs减少到只有一个:

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