2017-07-27 98 views
0

我以前这里的问题Variadic template, function as argument调用带有一个成员函数可变参数模板函数基于

我已经结束了下面一个简单的类,但我怎么使用std ::调用或一些其他方法来调用测试: :用Tester :: simple作为参数测试? http://en.cppreference.com/w/cpp/utility/functional/invoke#Example提供的例子对我来说不是很有帮助,我尝试了很多不同的使用std :: invoke的方法。

class Tester { 
public: 
    template<typename F, typename... Args> 
    decltype(auto) test(F&& f, Args&&... args) { 
     return std::forward<F>(f)(std::forward<Args>(args)...); 
    } 
    int simple(int i) { return i; } 
}; 

int main() 
{ 
    Tester t; 
    std::cout << t.test(t.simple, 3); // how do you modify this line such that the code compiles? 
} 

谢谢!

回答

2

一种方法是修改test()成员函数的定义,像这样:

class Tester { 
public: 
    template<typename F, typename... Args> 
    decltype(auto) test(F&& f, Args&&... args) { 
     return std::invoke(std::forward<F>(f), std::forward<Args>(args)...); 
    } 
    int simple(int i) { return i; } 
}; 

然后,我们可以通过一个成员函数指针test(),与该方法应该被称为第二个实例参数,然后函数的参数本身:

int main() 
{ 
    Tester t; 
    std::cout << t.test(&Tester::simple, t, 3); 
} 

这部作品的原因是因为std::invokespecial overload for pointers-to-members,这样

std::invoke(ptr-to-member, instance, args...); 

被称为

(instance.*ptr-to-member)(args...); 

这正是我们希望在这种情况下。

1

请注意,std::invoke的一部分C++ 17。在如果没有可用的情况下,所以它接受一个可能实现的test功能指针到成员函数和一个类的实例:

template<typename F, typename T, typename... Args> 
decltype(auto) test(F f, T&& t, Args&&... args) { 
    return (std::forward<T>(t).*f)(std::forward<Args>(args)...); 
} 

现在test接受指针TO-成员函数作为第一个参数,作为第二个参数的类的实例和任意数量的附加参数。

然后test可能被称为像:

Tester t; 
std::cout << t.test(&Tester::simple, t, 42); 

WANDBOX EXAMPLE

+0

现在它与非成员函数不兼容。试试't.test(放,“你好!”)'。 –

+0

@HenriMenke确实如此。据我所知,OP在这个问题上有兴趣处理成员函数。所以我为成员函数添加了一个简单的解决方案。现在,OP可以自由结合他的问题解决方案来实现所需的功能。或者,如果他的编译器允许他这样做,只需使用'std :: invoke'即可:) –

1

仅举另一种可能性,你可以包裹成员函数调用一个lambda并捕获实例t。在C++ 14中,我们可以使用通用lambda表达式,所以我们不必明确指定参数。

#include <iostream> 
#include <utility> 

class Tester { 
public: 
    template<typename F, typename... Args> 
    decltype(auto) test(F&& f, Args&&... args) { 
     return std::forward<F>(f)(std::forward<Args>(args)...); 
    } 
    int simple(int i) { return i; } 
}; 

int main() 
{ 
    Tester t; 
    std::cout << t.test([&t] (auto&&... args) { return t.simple(std::forward<decltype(args)>(args)...); }, 3); 
} 
相关问题