我认为这里应该使用
clang
。
我们可以从
draft C++ standard的第
6.4.2
节
switch语句中看到,这涉及到
上下文隐式转换。第
2段说(*接下来是我的强调):
条件应该是整数类型、枚举类型或类类型。如果是类类型,则条件会被上下文隐式转换(第4条)为整数或枚举类型。
我们可以看到我们需要使用的部分是
4
标准转换,而第
5段涵盖了这些情况,它说:
某些语言结构需要转换为具有指定类型集合之一的值。在这种上下文中出现的类类型E的表达式e被称为
上下文隐式转换为指定类型T,仅当e可以隐式转换为以下确定的类型T时才是良好形式:搜索E的转换函数,其返回类型为cv T或引用cv T,使得T由上下文允许。应该确切地有一个这样的T。
此内容不涉及第8.5节,该节通过明确引用第13.3节允许重载解析,而不允许重载解析我们无法使用:
template <typename T>
operator T () const
因此,没有歧义。
请注意,这与第4段不同,第4段涵盖了在“if”、“while”等上下文中的布尔转换,并且说(
我强调):
某些语言结构要求将表达式转换为布尔值。出现在这种上下文中的表达式e被认为是在上下文中转换为bool,并且仅当声明bool t(e) 的发明临时变量t(8.5)的形式良好时,它才是形式良好的。
这特别允许重载分辨率并直接引用覆盖此内容的第13.3节。允许它是有道理的,因为我们有一个特定的目标类型bool可转换到其中,在switch案例中我们没有。
为什么?
我们可以通过查看
N3323: A Proposal to Tweak Certain C++ Contextual Conversions, v3来解决这个问题。引用整篇论文可能有些困难,因此我将尝试引用足够的上下文。它说:
在C ++表达式出现的上下文经常影响表达式的评估,因此可能会对表达式施加要求,以确保这种评估是可能的。[...]
在四种情况下,FDIS(N3290)使用不同的语言来指定类似的上下文相关转换。在这四个上下文中,当操作数为类类型时,该类型必须具有“单个非显式转换函数”以适合的(上下文特定)类型。[...]
并包括:
[stmt.switch] / 2:“条件应为整数类型,枚举类型或具有单个非显式转换函数以整数或枚举类型存在的类类型(12.3)。”
并说:
在引言中提到的这四个情境中,主要问题似乎在于它们共同具有的有用但非常严格的要求,即将类限制为仅有一个转换运算符。另一个问题是当前措辞中“单一”限定符的范围。在类中必须只有一个转换函数,还是可以有多个转换函数,只要其中一个适合上下文即可?当前语言在这一点上似乎不太清楚。也不清楚生成适当类型引用的转换运算符是否是适当的转换运算符。(关于这一点的问题已于2011年2月21日发布到核心反射器上,但截至本文写作时未得到回答。)目前编译器实践似乎允许这样的运算符,但当前语言似乎不允许。为了解决所有这些问题,我们建议改用由[conv]/3定义的术语“上下文转换为bool”的经过验证的方法。因此,我们建议对[conv]/3进行适度补充,以定义上下文转换为其他指定类型,然后引用这个新定义。新的措辞如下:
某些其他语言结构需要类似的转换,但要将其转换为一个特定类型的值,该类型适用于该结构。在这种情况下出现的类类型E的表达式e被称为在上下文中隐含地转换为指定类型T,并且仅当e可以被隐含地转换为以下确定的类型T时才是良好的:在E中搜索返回类型为cv T或引用cv T的转换函数,使得T由上下文允许。应当恰好有一个这样的T。
注意
N3486: C++ Editor's Report, October 2012告诉我们
N3323
何时被纳入草案标准。
更新
提交了一个
gcc bug report。
int
。 - Some programmer dudeN3323
ж¶өзӣ–дәҶдёҠдёӢж–ҮиҪ¬жҚўе‘Ёеӣҙзҡ„йҖ»иҫ‘пјҢ并且е®ғејәзғҲжҢҮеҮәclang
еңЁиҝҷж–№йқўжҳҜжӯЈзЎ®зҡ„гҖӮ - Shafik Yaghmour