非静态成员函数的 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 表达式和类成员访问,对吧?
玩我最喜欢的编译器,我得到以下内容。
✓ 被编译器接受
namespace N { void f() {} }
using type = decltype(N::f);
type* pf = N::f;
好吧,我猜;N::f
是一个不带括号的 id 表达式,不命名一组重载函数。
✗ 被编译器拒绝
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
的理解是不是很糟糕? GCC后备箱错了吗? 两者都有? 没有? 卡穆洛克斯?
原因很简单,S::f
的使用对类成员是有限制的。
[expr.prim.id]
2 表示非静态数据成员或 类的非静态成员函数只能用于:
作为类成员
- 访问的一部分,其中对象表达式引用成员的类或从该类派生的类,或
- 形成指向成员的指针 ([expr.unary.op](,或
- 如果该 id-expression 表示非静态数据成员,并且它出现在未计算的操作数中。
最后一个项目符号(与代码相关的项目符号(仅适用于非静态数据成员。没有规定职能。
我只能推测为什么不允许这样做,尽管我之前问过这个问题。
值得注意的是,decltype(&S::f)
在这里用作指向成员函数的指针类型,
除非f
命名一组重载(成员(函数。
函数类型本身可以从指向成员函数类型的指针中提取。
如果成员函数符合 cv-or-ref 条件,则它具有可恶的函数类型。
这里缺少std特征 - 像Boost.CallableTraits这样的库会有所帮助。
相关文章:
- 非静态成员函数的 decltype 格式不正确吗?
- HTTP 响应格式不正确?
- 实例化具有不完整类型的类模板格式不正确(如果该类型是在之后定义的)
- 注意:"Entity_c::Entity_c(const Entity_c&)"被隐式删除,因为默认定义格式不正确:
- C++ std::vector 中的外部类(定义格式不正确)
- 输出使用 cout 转换为 ASCII 的文本时输出格式不正确,C++
- 为什么参考简历的格式不正确?
- 被隐式删除,因为默认定义格式不正确:
- 为什么 (int&)0 格式不正确?
- 下面的代码是格式不正确的 NDR 还是格式正确的代码
- 尝试访问类的私有成员以消除重载是否格式不正确
- 不正确的printf格式指定器编译
- 使用派生自 'std::tuple' 的元素在 'std::tuple' 上调用 'std::get' - 格式不正确
- 尝试使用 boost::asio 连接到 SOCKS 5 服务器,但我的连接请求格式不正确
- “在成员函数之外封闭类的定义中需要默认成员初始值设定项” - 我的代码格式不正确
- 为什么以下模板声明格式不正确
- C++构造函数被隐式删除,因为默认定义的格式不正确
- 错误:隐式删除,因为默认定义格式不正确(结构向量)
- 提升日志时间戳格式不正确
- 在 C++11 标准中哪里说 char* p = "abc" ;格式不正确?