Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我相信这是一个叮当作响的bug++;与访问类';政府的公共成员职能_C++_Language Lawyer_Public_Clang++ - Fatal编程技术网

C++ 我相信这是一个叮当作响的bug++;与访问类';政府的公共成员职能

C++ 我相信这是一个叮当作响的bug++;与访问类';政府的公共成员职能,c++,language-lawyer,public,clang++,C++,Language Lawyer,Public,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()(); } 但是它应该,因为表达式s.operator p()()访问对象s::s的公共成员函数。我错过什么了吗 如果

叮当作响的声音如下:

#include <iostream>

void f() { std::cout << "f()\n"; }

struct S {
    typedef void(*p)();
    operator p() { return f; }
};

int main()
{
    S s;
    s.operator p()();
}
但是它应该,因为表达式
s.operator p()()
访问对象
s::s
的公共成员函数。我错过什么了吗


如果我错了,我希望能引用标准中的一句话来支持答案。

这似乎是一个叮当声中的错误。我相信代码是正确的

Clang 4.0.0报告:

<source>:13:16: error: unknown type name 'p'; did you mean 'S::p'?
    s.operator p()();
           ^
:13:16:错误:未知类型名称“p”;你是说“S::p”吗?
s、 算子p()();
^
但是,从C++143.4.5/7[basic.lookup.classref]

如果id表达式是转换函数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
}
struct A{};
名称空间N{
结构A{
void g(){}
模板算子T();
};
}
int main(){
N::A;
a、 算子a();
//调用N::A::运算符N::A
}
-[结束示例]


在您的示例中,类型
p
应该在类中找到,而不需要限定。

您的链接说明了一切:“您的意思是'S::p'?”请将编译器错误粘贴到问题中,而不仅仅是链接到它们。转换运算符的名称查找使用类型匹配,而不是词汇(字符)匹配。即使您说了
s.operator decltype(&f)(
),查找也会成功。不过,这段代码看起来格式不错,因为规范中说“如果id表达式是转换函数id,则首先在对象表达式的类中查找其转换类型id,并使用名称(如果找到)。”。所以这闻起来真像是叮当作响中的一个bug……这里的问题是是否应该首先在类范围内查找
p
。gcc和clang有所不同。经过进一步分析,我认为我没有真正理解句子
的原因,否则它会在[basic.lookup.classref]/7中的整个后缀表达式的上下文中查找。请注意,所示示例无法编译。你能举个例子说明上面的句子有什么用处吗?在这个例子中,类型名
A
N::A
的上下文中被正确查找,给出了注入的类名,意思是
N::A
。在访问的对象中没有任何这样的运算符这一事实是一个单独的错误。下面是一个示例,其中在类类型的作用域中查找名称失败,但在整个后缀表达式的作用域中查找名称成功:在调用
b.operator a()中
,在
N::B
的范围内没有名称
A
,但是在调用函数
M::f
的范围内可以找到
M::A
。@aschepler感谢您的评论。我最终得出结论,链接中的示例显示了在整个后缀表达式的范围内使用名称查找。
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
}