我相信这是 clang++ 中与访问类的公共成员函数有关的错误

Posted

技术标签:

【中文标题】我相信这是 clang++ 中与访问类的公共成员函数有关的错误【英文标题】:I believe this is a bug in clang++ related to the access to a class's public member function 【发布时间】:2017-11-12 11:46:33 【问题描述】:

以下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 的公共成员函数。我错过了什么吗?

如果我错了,我会感谢标准的引用来支持答案。

【问题讨论】:

你的链接说明了一切:“你的意思是'S::p'吗?” 请将编译器错误粘贴到问题中,不要只是链接到它们。 转换运算符的名称查找使用类型匹配而不是词法(字符)匹配。即使您说s.operator decltype(&amp;f)()(),查找也会成功 这个代码看起来格式正确,因为规范说“如果 id-expression 是一个转换函数 ID,它的转换类型 ID 首先在对象的类中查找表达式和名称,如果找到,则使用。”。所以这真的闻起来像clang中的错误...... 这里的问题是p 是否应该首先在类范围内查找。 gcc 和 clang 不同。 【参考方案1】:

这似乎是 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.clas-s-ref]

如果id-expression是一个conversion-function-id,它的conversion-type-id首先在类中查找 对象表达式和名称(如果找到)将被使用。否则在整个上下文中查找 后缀表达式。在这些查找中的每一个中,只有表示其特化的类型或模板的名称 是否考虑了类型。

[示例:

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

—结束示例]

在您的示例中,类型 p 应该已经在类中找到而无需限定。

【讨论】:

经过进一步分析,我想我并没有真正理解[basic.lookup.clas-s-ref]/7中Otherwise it is looked up in the context of the entire postfix-expression这句话的原因。请注意,here 显示的示例无法编译。你能举个例子说明上面的句子有什么用处吗? 在该示例中,类型名称AN::A 的上下文中被正确查找,给出了注入类名称,这意味着N::A。您在访问的对象中没有任何此类运算符的事实是一个单独的错误。 这里是一个例子,类类型范围内的名字查找失败,但整个后缀表达式范围内的名字查找成功:coliru.stacked-crooked.com/a/8fa9ae6e5f261edc在调用b.operator A();中,有在N::B的范围内没有名字A,但是在调用函数M::f的范围内可以找到M::A @aschepler 感谢您的评论。我终于得出结论,链接中的示例显示了在整个后缀表达式范围内使用名称查找。

以上是关于我相信这是 clang++ 中与访问类的公共成员函数有关的错误的主要内容,如果未能解决你的问题,请参考以下文章

C++ 使用变量访问类的公共成员

类的公共成员及其访问

访问基类的公共成员失败

让公共成员变量访问 C++ 中同一类的私有成员

如何从他们自己的类的成员函数中访问公共变量? (C ++)

C ++ QT如何从QMainWindow布局访问QWidget的公共类成员