C++ 在switch语句中使用struct

C++ 在switch语句中使用struct,c++,gcc,c++03,C++,Gcc,C++03,我正在尝试创建一个可以在switch语句中使用的结构。我正在使用一系列wierd编译器,比如keilarmcc和老式的gcc4.7.1 这也意味着c++11不是一个选项 一段时间以来,这个想法确实奏效了: struct Test { const int a; Test() : a(1) {} template<typename T> operator T() const; operator int() const {return a;}

我正在尝试创建一个可以在switch语句中使用的结构。我正在使用一系列wierd编译器,比如keilarmcc和老式的gcc4.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;
}
struct测试
{
常数INTA;
Test():a(1){}
模板
算子T()常数;
运算符int()常量{返回a;}
};
...
试验t;
开关(t)
{
案例1:
打破
}
那很好。现在,我试图在不破坏与armcc的兼容性的情况下,迁移到更新版本的gcc

但现在gcc给了我这个:

error: ambiguous default type conversion from 'Test'
 switch(t)
         ^
error:   candidate conversions include 'template<class T> Test::operator T() const'
错误:来自“Test”的默认类型转换不明确
开关(t)
^
错误:候选转换包括“模板测试::运算符T()常量”
因为模板操作符没有主体,所以我不能真正理解歧义在哪里

有办法解决这个问题吗

switch(t)
{
case 1:
    break;
}
在这里,编译器不知道调用什么转换运算符;这是模棱两可的。它可以为一些不同的整数类型实例化模板转换运算符,或者调用
int
转换运算符。模板化转换运算符函数未定义这一事实对重载解析并不重要


最简单的解决方案是使用
开关(static_cast(t))
您可以分配给临时int:

int n = t;
switch (n) {
   ...
}
开关(t)
的上下文中,编译器考虑强制执行整数类型,包括
int
无符号int
。通过指定类型为
int
的变量,我们折叠波函数,强制它选择我们想要的转换,当我们到达
开关时,没有歧义


你也应该认真考虑你的模板转换运算符<代码>显式< /代码>,如果你可以的话,因为所有的转换都会导致令人不快的惊喜。

过载解析不关心函数是否有定义。最简单的修复方法是
开关(static_cast(t))
;我想不惜一切代价避免它?或者其他地方有其他函数为不同类型重载该运算符吗?在实际代码中,struct将enum隐藏在里面(类似于enum类),所以实际上我需要允许转换为enum并禁用其他所有内容。如果我读了模板操作符,在不同枚举之间会有隐式转换,我不想这样。你应该考虑升级你的编译器(例如在2015年12月)。您可以从下载一些更新鲜的编译器源代码并构建一个交叉编译器;我愿意不惜一切代价避免它;开关(n){…}
?我不明白,为什么int n=t工作而开关不工作!我会把它写下来作为答案,并加以解释。对。所以我们不能强迫编译器以其他方式选择转换吗?我尝试了重载转换(没有实体)所有我能记住的积分类型,但仍然模棱两可。(不幸的是,显式运算符是c++11特性)对不起,我应该发现c++03标记!我认为问题在于,转换被定义为太多(即>1)个整数类型,编译器不能选择一个作为“最佳”。如果只有一个整数类型的转换,您的问题就会得到解决。难道没有任何方法明确禁止某些转换吗?我想如果我在声明中没有定义,就会迫使编译器选择另一个实现。。