【问题标题】:What are the rules for function pointers and member function pointers to Standard functions?函数指针和成员函数指针指向标准函数的规则是什么?
【发布时间】:2012-11-22 22:56:16
【问题描述】:

将函数指针或成员函数指针指向标准函数的现有规则是什么?例如,像

auto p = &std::string::size;

这合法吗?如果我明确地请求正确的类型,它或多或少是合法的,所以即使有一个额外的实现添加重载std::string::size,它也会起作用?

【问题讨论】:

  • 我不认为这是合法的。 C++ 要求你声明变量的类型,不会为你推断。
  • @nonsensical 有人没有最新的 C++11!
  • @sftrabbit 看来我认为 C++ 标签是针对旧 C++ 而不是 11... .

标签: c++ rules standard-library member-function-pointers member-functions


【解决方案1】:

使用“正确”类型并不能让事情变得更好:除了virtual 函数,标准 C++ 库中的所有函数都可以有附加参数,只要这些是默认的。由于这些函数也可以用额外的重载声明(同样virtual 函数除外),您最终可能会尝试为重载集分配一个变量。因此,代码不可移植,也无法通过使用某种类型的强制转换或某些签名而不是 auto 来使其可移植。

相关引用是 17.6.5.5 [member.functions] 第 1 段:

一个实现可以在一个类中声明额外的非虚拟成员函数签名:
--- 通过将具有默认值的参数添加到成员函数签名;
— 通过用两个或多个具有等效行为的成员函数签名替换具有默认值的成员函数签名;和
— 通过为成员函数名称添加成员函数签名。

不过,我没有看到非成员函数的类似权限。不确定将这些弄乱的权限隐藏在哪里,但我相对确定这些也有一些狡猾的词。进一步看,根据 17.6.5.4 [global.functions] 第 3 段,似乎非成员函数受到更多限制:

实现不应声明带有附加默认参数的全局或非成员函数签名。

这意味着您可以获取非成员函数的地址,至少在指定所需的签名时。

【讨论】:

  • 该代码当然不是非法的,它只是具有特定于实现的行为。
  • @JosephMansfield,DietmarKuhl,这是否意味着my question 无法提供便携式答案?
  • @iammilind:正确:您不能便携地获取标准库类的成员函数的地址(如果该函数恰好是 virtual,我认为您可以,但无论如何这些都很少而且是所有protected)。如果您想要成员函数的函数对象,最好使用 lambda 函数在第一个参数上调用该成员并转发所有其他成员,例如:[](auto&& o){ return o.size(); }
  • Stephan T. Lavavej,顺便提到这是不允许的,但这可能是由于额外的重载。 youtu.be/zt7ThwVfap0?t=604
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 2012-10-03
  • 1970-01-01
相关资源
最近更新 更多