struct A{
operator auto(){
return 0;
}
};
int main(){
A a;
a.operator auto(); // #1
a.operator int(); // #2
}
GCC https://godbolt.org/z/3jdaK9接受 #2 是显式调用转换函数的正确方法,同时Clang https://godbolt.org/z/Ehf5vG接受#1。
看起来#1
由于以下规则,格式不正确:
dcl.spec.auto#6 https://timsong-cpp.github.io/cppwp/n4659/dcl.spec.auto#6
在本节未明确允许的上下文中使用 auto 或 decltype(auto) 的程序是格式错误的。
这个用法a.operator auto()
[dcl.spec.auto] 节中未明确允许,因此它应该是格式错误的。然而,对于GCC接受的第二种用法,标准并没有说conversion-function-id
哪里的conversion-type-id
is 替换为推导类型表示转换函数的名称。换句话说,所声明的conversion-function-id
声明中是operator auto
而不是operator int
。前者与声明的 declarator-id 具有相同的标记。根据语法,unqualified-idoperator auto
应该是该转换函数的名称。那么,如何显式调用这个转换函数呢?当转换函数包含占位符说明符时,标准中是否未指定转换函数的名称?
看来,这个规定还不够准确。
- From
10.1.7.4 The auto specifier
:
占位符类型可以与函数声明符一起出现在
decl-说明符-seq、类型说明符-seq、转换函数 ID, 或者
尾随返回类型,在此类声明符有效的任何上下文中。
准确地阅读,人们可能会在这里区分“可以”和更强的“只能”,即可能为编译器内在函数的自由度开辟空间(完全错误与未指定的行为)。
And 3.4.5 class member access
says:
7 如果 id-expression 是一个 conversion-function-id,则其
首先在对象的类中查找 conversion-type-id
表达式和名称(如果找到)将被使用。
如果 auto 关键字在该上下文中是否可以有效地成为完全限定的转换类型 ID,那么再次留有解释的空间。
你的问题本身可能需要进一步分支,即
- 运算符 auto() 使用的详细重载规则是什么,即它是否应该可用于已经在类定义级别上的常规候选人竞争? (Clang 和 Gcc 则不然,除了额外的运算符 int() ...之外,它们都先验地接受运算符 ...)
- 是否可以使用显式成员运算符引用(您的情况1)来调用运算符 auto() ,即有效地,它是否有一个(唯一的)可访问名称?允许这样做将与该关键字的所有其他明确允许的用例相矛盾。
我已经在几个 clang 修订版中看到了对此的显式测试,因此它的行为不是隐式命名约定应用程序的产物,而是显然是明确期望的行为。
正如评论中已经提到的,至少与 gcc 相比,Clang 的行为在整体上更加一致,因为它完全清楚,其中 auto 关键字用于类型推导,以及名称/函数 ID 解析。那里的运算符 auto() 被作为一个更显式的自己的实体来处理,而对于 gcc,它具有类似于 lambda 的匿名字符,但即使对于显式成员运算符访问方式,它也会参与候选人竞争。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)