c++ - 非静态成员函数的 decltype 格式不正确吗?

标签 c++ c++14 language-lawyer c++17 decltype

我不确定是否完全理解[dcl.type]/4.3 :

For an expression e, the type denoted by decltype(e) is defined as follows:

  • [...]
  • (4.3) otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
  • [...]

对我来说,强调的部分同时适用于id-expressionclass member access,对吧?

使用我最喜欢的编译器,我得到以下结果。

✓ 被编译器接受

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 An id-expression that denotes a non-static data member or non-static member function of a class can only be used:

  • as part of a class member access in which the object expression refers to the member's class or a class derived from that class, or
  • to form a pointer to member ([expr.unary.op]), or
  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

最后一个与您的代码相关的项目符号仅适用于非静态数据成员。没有提供功能。

我只能推测为什么不允许这样做,though I previously asked that question .

关于c++ - 非静态成员函数的 decltype 格式不正确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52520276/

相关文章:

c++ - 作为非类型模板参数的引用

c++ - 为什么我不能声明一个同时具有模板容器和模板包含值的类型?

c++ - 在 C++ 中读取压缩的二进制文件

c++ - 支持 C++14 lambda 的 ros 包

从函数返回的 C++ 类型的 lambda 闭包

c++ - 如果特化已经被隐式实例化,它是否被隐式实例化?

c - a[a[0]] = 1 会产生未定义的行为吗?

c++ - OpenGL:绘制多边形时,如果第一个顶点位于屏幕空间之外怎么办(三角扇)

c++ - 在 C++ 中重载 +=

c++ - 使用 Visual Studio 2015 : error C3546 在 lambda 中扩展参数包