- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有以下代码:
#include <functional>
struct X {
int get() const& {
return 42;
}
};
template<typename Func>
std::result_of_t<Func(X)> Apply(Func fn) {
X x;
return fn(x);
}
int main(void) {
Apply([](X const& x){return x.get();});
//Apply(std::mem_fn(&X::get)); // does not compile
}
第一次调用 Apply
编译正常,但如果我取消注释第二次调用,我会得到以下编译错误:
main.cpp:16:5: error: no matching function for call to 'Apply'
Apply(std::mem_fn(&X::get)); // does not compile
^~~~~
main.cpp:10:27: note: candidate template ignored: substitution failure [with Func = std::_Mem_fn<int (X::*)() const &>]: no type named 'type' in 'std::result_of<std::_Mem_fn<int (X::*)() const &> (X)>'
std::result_of_t<Func(X)> Apply(Func fn) {
^
我以某种方式期望这两个调用可以互换使用,并且 std::mem_fn
只是“会做正确的事”。谁能解释一下,这里发生了什么?
最佳答案
问题出在这里:
int get() const& {
// ^^^
您的成员函数是左值引用限定的。在你的 Apply()
中:
template<typename Func>
std::result_of_t<Func(X)> Apply(Func fn) {
return fn(X{});
}
您正在使用右值调用它。这给我们带来了这两个表达方式之间的[令我非常惊讶]的区别:
X{}.get(); // ok
(X{}.*&X::get)(); // ill-formed
在特别是指向成员的指针运算符上,成员指针的引用限定符根据对象的值类别进行检查。来自 [expr.mptr.oper]:
In a
.*
expression whose object expression is an rvalue, the program is ill-formed if the second operand is a pointer to member function with ref-qualifier&
. In a.*
expression whose object expression is an lvalue, the program is ill-formed if the second operand is a pointer to member function with ref-qualifier&&
.
所以第一个表达式没问题,get()
是 const&
限定的,但右值可以绑定(bind)到它。第二个表达方式不行——规则只是明确禁止它。
所以你看到的行为是完全正确的 - mem_fn
是通过直接调用成员函数定义的,它在右值上是错误的,所以 Apply
被从过载集。如果不是,那么实例化主体将是一个硬错误。
lambda 起作用的原因是临时 X
绑定(bind)到 lambda 的引用参数。 get()
然后在左值函数参数上调用 - 而不是在传递给它的临时参数上。但即使没有它,直接在临时对象上调用 get()
仍然没问题。
关于c++ - result_of 没有为 mem_fn 定义类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42113821/
这是一个后续问题 mem_fn to function of member object 这是当前代码。 #include #include #include struct Int {
KDE/PIM Zanshin 项目在其代码中的多个位置使用了 std::mem_fn,结果证明至少有 1 个版本的 Apple clang(随 OS X 10.9 提供的最新 Xcode 提供的版本
我很困惑为什么需要 std::mem_fn。 我有一个函数接受任何可调用对象(lambda、函数指针等),并将其绑定(bind)到一个参数。 例如: template void Class::DoBi
我正在修补 std::mem_fn,但无法设法将其绑定(bind)到结构成员的数据/函数(更深一层)。 我希望代码能比我描述的更好地说明问题,因为我不熟悉术语。 #include struct In
编译以下代码时,Visual Studio报告: \main.cpp(21): error C2664: 'std::_Call_wrapper,false> std::mem_fn(int Clas
我已经实现了一个C++程序,该程序创建了三个不同的Person对象。这些对象被共享并存储在 vector 中。 函数getVector()以const std::vector>&作为输入并返回std:
我有以下片段: struct Foo { Foo(int num):num_(num){} void print_add(int i) const { std::cout vpf{
我有一个更复杂的包装类版本,它封装了如下用户类型的 std::vector。 struct UserType1Encapsulator { template UserType1Encap
我可以用 C++ 实现以下功能吗?在调用回调方法之前,我想保持未指定 myInstance 变量,而不是将其包含在 boost::bind 实例中。 MyClass *myInstance; void
我有一个带有默认参数的成员函数的类。 struct Class { void member(int n = 0) {} }; 通过 std::tr1::mem_fn 我可以调用它: C
编译以下代码时,Visual Studio 报告: \main.cpp(21): error C2664: 'std::_Call_wrapper,false> std::mem_fn(int Cla
有人可以推荐 tr1 的 mem_fn 和绑定(bind)实用程序的一些很酷的实际用途吗?我不需要深奥的 c++ 来开发库。只是一些利用这些的应用程序级编码。 任何帮助将不胜感激。 最佳答案 我已将
考虑这个人为的例子: template void funny_transform(Iter first, Iter last, vector& v) { transform(first, la
考虑 the following code : struct A { int& getAttribute(); const int& getAttribute() const; };
这是由于 mem_fn() 的实现没有定义 __forceinline/inline/__attribute__((always_inline)) 造成的吗?是否可以解决这个问题,例如使用自己的 me
我正在使用 C++11 和 MSVC2013 尝试在我的类中使用函数指针来拥有自己的成员函数。 class MyClass { public: // ... QColor Co
auto 很好,但我需要在类中声明一个成员,而不是堆栈中的变量。 decltype 有效,但不知何故看起来很奇怪 class Automation { void _init_state(int
我想把这个结果: std::tr1::mem_fn(&ClassA::method); 在一个变量中,这个变量的类型是什么? 看起来像这样: MagicalType fun = std::tr1::m
我理解在其类之外传递成员函数地址的基本问题。我觉得 mem_fn() 可能是解决方案,但我在具体细节上遇到了麻烦。 我在类 p 中有一个成员函数,当前声明为 typedef void (*valNam
我有以下代码: #include struct X { int get() const& { return 42; } }; template std::result
我是一名优秀的程序员,十分优秀!