c++ - 我们不能在未评估的上下文中命名非静态成员函数有什么原因吗?

标签 c++ language-lawyer

阅读时[expr.prim.id] , 人们会看到这一点

An id-expression that denotes a non-static data member or non-static member function of a class can only be used:

  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

我不清楚上面的项目符号仅适用于数据成员这一事实。凭直觉,我希望以下内容格式正确:

#include <type_traits>

using func = int();

class bar {
  func foo; // This is valid, and not the subject of the question
};

static_assert(std::is_same<decltype(bar::foo), func>::value, "No Symmetry!");

但是 decltype() 甚至在静态断言被检查之前就已经是错误格式了。

我是否遗漏了一些歧义?

最佳答案

Is there some ambiguity I'm missing?

事实上,作为该成员函数声明的一部分添加了大量类型信息。

虽然 func 肯定可以用来声明该成员,但故事并没有就此结束。一旦声明了成员,它的类型就完成了。这涉及添加一些其他内容,例如 cv-qualifersref-qualifiers。在 foo 的情况下,所有默认的隐式都已确定,并且它们成为 bar::foo 类型的一部分。由 [dcl.fct]/8 指定:

The return type, the parameter-type-list, the ref-qualifier, the cv-qualifier-seq, and the exception specification, but not the default arguments, are part of the function type.

没有办法在上面的foo声明中明确指定它们(尽管它们可能被添加到func),但它们通常可以被添加:

class bar {
  int foo() const volatile &&;
};

它们是函数类型的一部分,如果它们出现,decltype(bar::foo) 应该解决它们(如果我收集正确,即使它们没有出现)。

当我们尝试评估 decltype(bar::foo) 时,const volatile && 去了哪里?

  • 它应该被忽略吗?那是可以做到的。但是丢失类型信息很少是一件好事。
  • 我们是否应该保留它,并且类型 decltype 评估为指向成员函数的指针?
    这也行得通,但现在它不同于数据成员在未计算的上下文中命名时的行为方式。我们引入了差异。
  • 是否应该保留它并将类型解析为其他类型?也许像 int(foo const volatile&&)int() const volatile &&(另一种形式的函数类型)?这打破了人们期望的对称性,并且再次成为数据成员的差异。

没有简单或明显的方法可以让它始终有效。因此,与其让一个用途有限的功能变得复杂,不如将其视为格式错误。

关于c++ - 我们不能在未评估的上下文中命名非静态成员函数有什么原因吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47263793/

相关文章:

c++ - 将 std::string 写入可比较的 *time* 解析器,这可能会失败

c - 通过定义明确的 offsetof 访问成员吗?

c++ - 使用 using 声明时,非限定名称查找如何工作?

c++ - 重载解决方案:是否首选直接转换运算符(作为复制省略的结果)?

c++ - 如果将其用作模板参数,是否需要使用 typename 来限定从属名称?

c++ - VS2017调试简单程序时出现访问冲突(RtlActivateActivationContextUnsafeFast)

c++ - 错误 C2248 无法访问类 'boost::asio::basic_io_object<IoObjectService> 中声明的私有(private)成员

c++ - 返回值优化 : ho can I avoid copy construction of huge STL containers.

c++ - 动态转换 C++ 的奇怪问题

c - 相同的匿名结构是否兼容?