繁体   English   中英

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

[英]Is decltype of a non-static member function ill-formed?

我不太清楚[dcl.type]/4.3

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

  • [...]
  • (4.3)否则,如果e是未加密码的id表达式或未加密的类成员访问,则decltype(e)是由e命名的实体的类型。 如果没有这样的实体,或者如果e命名了一组重载函数,那么该程序就会形成错误 ;
  • [...]

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

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

✓由编译器接受

namespace N { void f() {} }
using type = decltype(N::f);
type* pf = N::f;

我觉得可以吧; 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;

好; 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;

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


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

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

[expr.prim.id]

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

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

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

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

值得注意的是, decltype(&S::f)在这里作为指向成员函数的指针类型,
除非f命名一组重载(成员)函数。

函数类型本身可以从指向成员函数的类型中提取。
如果成员函数是cv-or-ref限定的,那么它具有可恶的函数类型
这里缺乏标准特征 - 像Boost.CallableTraits这样的库帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM