std::mem_fn 返回的函数对象是否需要 const 重载

Is function object returned by std::mem_fn required to have a const overload

当我 运行 使用 libc++ 编写此代码时:

struct foo
{
    foo(int x) : x(x)
    {}
    int x;
};

int main()
{
    const auto select_x = std::mem_fn(&foo::x);
    foo f(1);
    printf("%i\n", select_x(f));
}

我收到这样的错误:

mem_fn.cpp:16:20: error: no matching function for call to object of type
      'const std::__1::__mem_fn<int foo::*>'
    printf("%i\n", select_x(f));
                   ^~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:1224:11: note: 
      candidate function not viable: 'this' argument has type 'const
      std::__1::__mem_fn<int foo::*>', but method is not marked const
          operator() (_ArgTypes&&... __args)
          ^

libc++ 似乎缺少 const 重载。它使用 libstdc++ 工作。这是 libc++ 中的错误吗?或者标准是否需要 const 过载?

我没有看到有关 mem_fn 返回的包装器的常量可调用性的任何标准。来自 [func.memfn](引用 N4140):

template<class R, class T> unspecified mem_fn(R T::* pm);

1 Returns: A simple call wrapper (20.9.1) fn such that the expression fn(t, a2, ..., aN) is equivalent to INVOKE (pm, t, a2, ..., aN) (20.9.2). fn shall have a nested type result_type that is a synonym for the return type of pm when pm is a pointer to member function.

2 The simple call wrapper shall define two nested types named argument_type and result_type as synonyms for cv T* and Ret, respectively, when pm is a pointer to member function with cv-qualifier cv and taking no arguments, where Ret is pm’s return type.

3 The simple call wrapper shall define three nested types named first_argument_type, second_argument_type, and result_type as synonyms for cv T*, T1, and Ret, respectively, when pm is a pointer to member function with cv-qualifier cv and taking one argument of type T1, where Ret is pm’s return type.

4 Throws: Nothing.

对 [func.def] 的引用(尽管 简单调用包装器 实际上在 [func.require] 中定义)同样没有启发性。这几乎只能保证 returns 可以直接使用。

尽管如此,作为实施质量问题,我看不出为什么包装器不应该是常量调用的,看起来这实际上已经被修复了 over a year ago。您可能想尝试更新 XCode 以查看是否可以获取更新版本的库。