- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
问题最初出现在this question .考虑以下代码:
class Var
{
public:
operator int () const
{ return 0; }
template <typename T>
operator T () const
{ return T(); }
};
int main()
{
Var v;
switch (v)
{ }
}
没有 operator int() const { return 0; }
,g++ 和 clang reject代码。
然而,上面的代码,使用operator int()
,是accepted by clang 但是rejected通过 g++ 并出现以下错误:
main.cpp:17:14: error: default type conversion can't deduce template argument for 'template<class T> Var::operator T() const'
switch (v)
^
哪个编译器是正确的?
最佳答案
我相信 clang
在这里是正确的。
从draft C++ standard可以看出6.4.2
switch 语句,这涉及上下文隐式转换。第 2 段说(*强调我的 future ):
The condition shall be of integral type, enumeration type, or class type. If of class type, the condition is contextually implicitly converted (Clause 4) to an integral or enumeration type.
我们可以看到我们需要使用的部分是 4
Standard conversions 段落 5 涵盖了这些情况,它说:
Certain language constructs require conversion to a value having one of a specified set of types appropriate to the construct. An expression e of class type E appearing in such a context is said to be contextually implicitly converted to a specified type T and is well-formed if and only if e can be implicitly converted to a type T that is determined as follows: E is searched for conversion functions whose return type is cv T or reference to cv T such that T is allowed by the context. There shall be exactly one such T.
这没有引用 8.5
节,它通过特别引用 13.3
节来允许重载解析,而不允许我们不能使用的重载解析:
template <typename T>
operator T () const
因此没有歧义。
请注意,这与 4 段不同,后者涵盖了 if、while 等上下文中的bool 转换。 .. 并说(强调我的):
Certain language constructs require that an expression be converted to a Boolean value. An expression e appearing in such a context is said to be contextually converted to bool and is well-formed if and only if the declaration bool t(e); is well-formed, for some invented temporary variable t (8.5).
它特别允许重载解析并直接引用涵盖此内容的 13.3
部分。这是允许的,因为我们有一个特定的目标类型 bool 可以转换为我们在 switch 情况下没有的目标类型。
为什么
我们可以通过查看 N3323: A Proposal to Tweak Certain C++ Contextual Conversions, v3 来解决这个问题它涵盖了这个问题。很难引用整篇论文,所以我会尝试引用足够多的上下文。它说:
The context in which a C++ expression appears often influences how the expression is evaluated, and therefore may impose requirements on the expression to ensure such evaluation is possible. [...]
In four cases, the FDIS (N3290) uses different language to specify an analogous contextdependent conversion. In those four contexts, when an operand is of class type, that type must have a “single non-explicit conversion function” to a suitable (context-specific) type. [...]
并包括:
[stmt.switch]/2: “The condition shall be of integral type, enumeration type, or of a class type for which a single non-explicit conversion function to integral or enumeration type exists (12.3).”
并说:
The principal issue, in each of the four contexts cited in the Introduction, seems to lie in their common helpful but very strict requirement that limits a class to only one conversion operator [...]
Another concern is the scope of the qualifier “single” in the current wording. Must there be but a single conversion function in the class, or may there be several so long as a single one is appropriate to the context?
The current language seems unclear on this point. It is also unclear whether a conversion operator that produces a reference to an appropriate type is an appropriate conversion operator. (A question on this point was posted to the Core reflector on 2011-02-21, but has gone unanswered as of this writing.) Current compiler practice seems to admit such operators, but the current language seems not to.
并提议:
To address all these concerns, we recommend instead to use the proven approach typified by the term contextually converted to bool as defined in [conv]/3. We therefore propose a modest addition to [conv]/3 to define contextual conversion to other specified types, and then appeal to this new definition.
新语言如下;
Certain other language constructs require similar conversion, but to a value having one of a specified set of types appropriate to the construct. An expression e of class type E appearing in such a context is said to be contextually implicitly converted to a specified type T and is well-formed if and only if e can be implicitly converted to a type T that is determined as follows: E is searched for conversion functions whose return type is cv T or reference to cv T such that T is allowed by the context. There shall be exactly one such T.
备注N3486: C++ Editor's Report, October 2012向我们展示 N3323
何时被纳入标准草案。
更新
提交了 gcc bug report .
关于c++ - 在 switch 语句的条件下同时具有模板和非模板转换运算符的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51329748/
这是代码片段。 请说出这种用小内存存储大数据的算法是什么。 public static void main(String[] args) { long longValue = 21474836
所以我使用 imap 从 gmail 和 outlook 接收电子邮件。 Gmail 像这样编码 =?UTF-8?B?UmU6IM69zq3OvyDOtc68zrHOuc67IG5ldyBlbWFpb
很久以前就学会了 C 代码;想用 Scheme 尝试一些新的和不同的东西。我正在尝试制作一个接受两个参数并返回两者中较大者的过程,例如 (define (larger x y) (if (> x
Azure 恢复服务保管库有两个备份配置选项 - LRS 与 GRS 这是一个有关 Azure 恢复服务保管库的问题。 当其驻留区域发生故障时,如何处理启用异地冗余的恢复服务保管库?如果未为恢复服务启
说,我有以下实体: @Entity public class A { @Id @GeneratedValue private Long id; @Embedded private
我有下一个问题。 我有下一个标准: criteria.add(Restrictions.in("entity.otherEntity", getOtherEntitiesList())); 如果我的
如果这是任何类型的重复,我会提前申请,但我找不到任何可以解决我的具体问题的内容。 这是我的程序: import java.util.Random; public class CarnivalGame{
我目前正在使用golang创建一个聚合管道,在其中使用“$ or”运算符查询文档。 结果是一堆需要分组的未分组文档,这样我就可以进入下一阶段,找到两个数据集之间的交集。 然后将其用于在单独的集合中进行
是否可以在正则表达式中创建 OR 条件。 我正在尝试查找包含此类模式的文件名列表的匹配项 第一个案例 xxxxx-hello.file 或者案例二 xxxx-hello-unasigned.file
该程序只是在用户输入行数时创建菱形的形状,因此它有 6 个 for 循环; 3 个循环创建第一个三角形,3 个循环创建另一个三角形,通过这 2 个三角形和 6 个循环,我们得到了一个菱形,这是整个程序
我有一个像这样的查询字符串 www.google.com?Department=Education & Finance&Department=Health 我有这些 li 标签,它们的查询字符串是这样
我有一个带有静态构造函数的类,我用它来读取 app.config 值。如何使用不同的配置值对类进行单元测试。我正在考虑在不同的应用程序域中运行每个测试,这样我就可以为每个测试执行静态构造函数 - 但我
我正在寻找一个可以容纳多个键的容器,如果我为其中一个键值输入保留值(例如 0),它会被视为“或”搜索。 map, int > myContainer; myContainer.insert(make_
我正在为 Web 应用程序创建数据库,并正在寻找一些建议来对可能具有多种类型的单个实体进行建模,每种类型具有不同的属性。 作为示例,假设我想为“数据源”对象创建一个关系模型。所有数据源都会有一些共享属
(1) =>CREATE TABLE T1(id BIGSERIAL PRIMARY KEY, name TEXT); CREATE TABLE (2) =>INSERT INTO T1 (name)
我不确定在使用别名时如何解决不明确的列引用。 假设有两个表,a 和 b,它们都有一个 name 列。如果我加入这两个表并为结果添加别名,我不知道如何为这两个表引用 name 列。我已经尝试了一些变体,
我的查询是: select * from table where id IN (1,5,4,3,2) 我想要的与这个顺序完全相同,不是从1...5,而是从1,5,4,3,2。我怎样才能做到这一点? 最
我正在使用 C# 代码执行动态生成的 MySQL 查询。抛出异常: CREATE TABLE dump ("@employee_OID" VARCHAR(50)); "{"You have an er
我有日期 2016-03-30T23:59:59.000000+0000。我可以知道它的格式是什么吗?因为如果我使用 yyyy-MM-dd'T'HH:mm:ss.SSS,它会抛出异常 最佳答案 Sim
我有一个示例模式,它的 SQL Fiddle 如下: http://sqlfiddle.com/#!2/6816b/2 这个 fiddle 只是根据 where 子句中的条件查询示例数据库,如下所示:
我是一名优秀的程序员,十分优秀!