【问题标题】:Using struct in a switch statement在 switch 语句中使用结构
【发布时间】:2015-12-08 09:34:24
【问题描述】:

我正在尝试创建一个可以在 switch 语句中使用的结构。我正在使用一堆奇怪的编译器,比如 keil armcc 和老式 gcc 4.7.1。

这也意味着 c++11 不是一个选项。

这个想法确实奏效了一段时间:

struct Test
{
    const int a;

    Test() : a(1) {}

    template<typename T>
    operator T() const;

    operator int() const {return a;}

};

...

Test t;

switch(t)
{
case 1:
    break;
}

编译得很好。现在我正在尝试在不破坏与 armcc 的兼容性的情况下迁移到更新版本的 gcc。

但是现在 gcc 给了我这个:

error: ambiguous default type conversion from 'Test'
 switch(t)
         ^
error:   candidate conversions include 'template<class T> Test::operator T() const'

由于模板运算符没有正文,我无法真正理解歧义在哪里。

有没有办法解决这个问题?

【问题讨论】:

  • 重载解析不关心函数是否有定义。最简单的修复方法是switch (static_cast&lt;int&gt;(t))
  • 使用实际演员表是我最后的手段;我想不惜一切代价避免它。
  • 只是摆脱template&lt;typename T&gt; operator T() const;?或者您在其他地方是否有其他函数为不同类型重载该运算符?
  • 在结构隐藏枚举的实际代码中(有点枚举类),所以实际上我需要允许转换为枚举并禁用其他所有内容。如果我读过模板运算符,不同枚举之间会有隐式转换,我不希望这样。
  • 您应该考虑升级您的编译器(例如,在 2015 年 12 月升级到 GCC 5.3)。您可以从gcc.gnu.org 下载一些更新的编译器源代码并构建一个交叉编译器。

标签: c++ gcc c++03


【解决方案1】:

您可以分配给一个临时 int:

int n = t;
switch (n) {
   ...
}

switch (t) 的上下文中,编译器会考虑强制转换为整数类型,包括intunsigned intlong。通过分配给int 类型的变量,我们折叠波函数强制它选择我们想要的转换,当我们到达switch 时没有歧义。

如果可以的话,您还应该认真考虑将模板转换运算符设为explicit,因为包罗万象的转换可能会导致令人不快的意外。

【讨论】:

  • 对。那么我们不能强制编译器以其他方式选择转换吗?我尝试为我记得的所有整数类型重载转换(没有主体),但它仍然模棱两可。 (不幸的是,显式运算符是 c++11 的特性)
  • 对不起,我应该发现了 C++03 标签!我认为问题在于为太多(即>1)整数类型定义了转换,并且编译器无法选择一个作为“最佳”。如果只有一次转换为整数类型,你的问题就解决了。
  • 有没有办法明确禁止某些转换?我认为如果我在没有定义的情况下进行声明,那将迫使编译器选择另一个实现..
【解决方案2】:
switch(t)
{
case 1:
    break;
}

这里编译器不知道调用什么转换运算符;这是模棱两可的。它可以为几种不同的整数类型实例化您的模板化转换运算符,或者调用您的int 转换运算符。模板化转换运算符函数未定义这一事实与重载决议无关。

最简单的解决方案是使用switch (static_cast&lt;int&gt;(t))

【讨论】:

  • 使用实际演员表是我最后的手段;我想不惜一切代价避免它。
  • int n=t; switch (n) {...} ?
  • 我不明白,为什么 int n=t 有效而 switch 无效!
  • 我会把它写下来作为答案,并附上解释。
猜你喜欢
  • 2018-06-16
  • 2016-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-27
  • 2021-12-08
  • 1970-01-01
相关资源
最近更新 更多