我相信这是 clang++ 中与访问 class 的 public 成员函数相关的错误
I believe this is a bug in clang++ related to the access to a class's public member function
以下doesn't compile clang:
#include <iostream>
void f() { std::cout << "f()\n"; }
struct S {
typedef void(*p)();
operator p() { return f; }
};
int main()
{
S s;
s.operator p()();
}
产量:
main.cpp:13:16: error: unknown type name 'p'; did you mean 'S::p'?
s.operator p()();
^
S::p
main.cpp:6:19: note: 'S::p' declared here
typedef void(*p)();
^
但它应该,因为表达式 s.operator p()()
访问对象 S::s
的 public 成员函数。我错过了什么吗?
如果我错了,我将不胜感激来自支持答案的标准的引用。
这似乎是 Clang 中的一个错误。我相信代码是正确的。
Clang 4.0.0 报告:
<source>:13:16: error: unknown type name 'p'; did you mean 'S::p'?
s.operator p()();
^
但是,从 C++14 3.4.5/7 [basic.lookup.classref]
If the id-expression is a conversion-function-id, its conversion-type-id is first looked up in the class of the
object expression and the name, if found, is used. Otherwise it is looked up in the context of the entire
postfix-expression. In each of these lookups, only names that denote types or templates whose specializations
are types are considered.
[ Example:
struct A { };
namespace N {
struct A {
void g() { }
template <class T> operator T();
};
}
int main() {
N::A a;
a.operator A();
// calls N::A::operator N::A
}
— end example ]
在您的示例中,类型 p
应该已在 class 中找到而无需限定。
以下doesn't compile clang:
#include <iostream>
void f() { std::cout << "f()\n"; }
struct S {
typedef void(*p)();
operator p() { return f; }
};
int main()
{
S s;
s.operator p()();
}
产量:
main.cpp:13:16: error: unknown type name 'p'; did you mean 'S::p'? s.operator p()(); ^ S::p main.cpp:6:19: note: 'S::p' declared here typedef void(*p)(); ^
但它应该,因为表达式 s.operator p()()
访问对象 S::s
的 public 成员函数。我错过了什么吗?
如果我错了,我将不胜感激来自支持答案的标准的引用。
这似乎是 Clang 中的一个错误。我相信代码是正确的。
Clang 4.0.0 报告:
<source>:13:16: error: unknown type name 'p'; did you mean 'S::p'?
s.operator p()();
^
但是,从 C++14 3.4.5/7 [basic.lookup.classref]
If the id-expression is a conversion-function-id, its conversion-type-id is first looked up in the class of the object expression and the name, if found, is used. Otherwise it is looked up in the context of the entire postfix-expression. In each of these lookups, only names that denote types or templates whose specializations are types are considered.
[ Example:
struct A { }; namespace N { struct A { void g() { } template <class T> operator T(); }; } int main() { N::A a; a.operator A(); // calls N::A::operator N::A }
— end example ]
在您的示例中,类型 p
应该已在 class 中找到而无需限定。