非静态成员函数的decltype是不正确的吗?

YSC*_*YSC 7 c++ decltype language-lawyer c++14 c++17

我不确定完全明白[dcl.type]/4.3:

对于表达式e,表示的类型decltype(e)定义如下:

  • [...]
  • (4.3)否则,如果e是未加密码的id-expression或不加括号的类成员访问,decltype(e)则是名为的实体的类型e.如果不存在这样的实体,或者如果e名称的组重载功能,该程序是形成不良的 ;
  • [...]

对我来说,强调的部分都适用于id-expression类成员访问,对吧?

玩我最喜欢的编译器,我得到以下内容.

✓由编译器接受

namespace N { void f() {} }
using type = decltype(N::f);
type* pf = N::f;
Run Code Online (Sandbox Code Playgroud)

我觉得可以吧; N::f是一个未加括号的id-expression,并没有命名一组重载函数.

✗编译器拒绝

namespace N { void f() {} void f(int) {} }
using type = decltype(N::f); // error: decltype cannot resolve address of overloaded function
type* pf = N::f;
Run Code Online (Sandbox Code Playgroud)

好; N::f命名一组重载函数.

✗编译器拒绝

struct S { void f(){} };
using type = decltype(S::f); // error: invalid use of non-static member function 'void S::f()'
type* pf = &S::f;
Run Code Online (Sandbox Code Playgroud)

哼?S::f会命名一组一个重载函数?


总而言之,我的理解是不是[dcl.type]/4.3很糟糕?是gcc trunk错吗?都?没有?kamoulox?

Sto*_*ica 9

原因很简单,S::f对类成员的使用受到限制.

[expr.prim.id]

2只能使用表示非静态数据成员或类的非静态成员函数的id表达式:

  • 作为类成员访问的一部分,其中对象表达式引用成员的类或从该类派生的类,或
  • 形成指向成员的指针([expr.unary.op]),或
  • 如果该id-expression表示非静态数据成员,则它出现在未评估的操作数中.

最后一个子弹,即与您的代码相关的子弹,仅适用于非静态数据成员.没有功能规定.

我只能推测为什么不允许这样做,尽管我之前曾问过这个问题.