0

我在理解为什么以下代码无法编译时遇到了一些麻烦

#include <iostream>
#include <typeinfo>

#define PRINT_FUNC() {std::cout << __PRETTY_FUNCTION__ << std::endl;}

struct Obj {
    Obj(){PRINT_FUNC();}
    int run (float f, char *c) {
        PRINT_FUNC();
        return 0;
    }

    int fly () {
        PRINT_FUNC();
        return 0;
    }
};

template <typename OBJ, typename R, typename ... Args>
void call_obj_func (OBJ &&o, R(OBJ::*fn)(Args...), Args ... args) {
    PRINT_FUNC();
    (o.*fn)(args...);
}

int main () {
    Obj o;
    call_obj_func(o, &Obj::fly);
}

对于 call_obj_func 函数,我希望 OBJ 的类型同时用于 rvlaue 和 lvalue 类型。但是,当使用左值类型调用时,编译器会抱怨使用以下类型存在歧义:Obj 和 Obj&

这意味着编译器不确定是使用 obj 的副本还是对 obj 的引用。

我确信存在一些语法错误,因为我希望函数 call_obj_func 使用左值和右值类型进行编译。

我的假设是成员函数指针,因为语法 (Obj&::*fn) 和 (Obj::*fn) 可能具有不同的语义。(虽然我无法在任何地方找到差异)。

4

1 回答 1

0

你可以写

template <typename OBJ, typename Method, typename ... Args>
void call_obj_func (OBJ &&o, const Method& fn, Args&& ... args) {
    PRINT_FUNC();
    (std::forward<OBJ>(o).*fn)(std::forward<Args>(args)...);
}

现场演示

As currently, you have conflict with type deduction (Obj& vs Obj, and you may have similar issues with args)

于 2015-08-08T09:34:13.363 回答