我试图创建一个函数重载因此它只能结合(工程)成员函数。我接过来一看在std::mem_fn
http://en.cppreference.com/w/cpp/utility/functional/mem_fn模板语法来代替唯一的成员函数
template <class Ret, class T>
/* unspecified */ mem_fn (Ret T::* pm);
函数签名所以我构建我的参数,例如
template <typename R, typename F>
auto call_me(R C::* func) {
return (mContainer.*func);
}
不过,后来我得到这个错误
.\template.cpp: In function 'int main()':
.\template.cpp:29:49: error: no matching function for call to 'MyClass<int, std::vector<int> >::call_me(std::vector<int>::size_type (std::vector<int>::*)() const noexcept)'
cout << test.call_me(&std::vector<int>::size) << endl;
^
.\template.cpp:16:10: note: candidate: template<class R, class F> auto MyClass<T, C>::call_me(R C::*) [with R = R; F = F; T = int; C = std::vector<int>]
auto call_me(R C::* func) {
^~~~~~~
.\template.cpp:16:10: note: template argument deduction/substitution failed:
.\template.cpp:29:49: note: couldn't deduce template parameter 'F'
cout << test.call_me(&std::vector<int>::size) << endl;
我之所以我试图做到这一点,所以我可以有一个适用于通用lambda和功能对象的重载以及适用于membe的另一个重载r功能指针。这是我想要实现的一个最简单的例子。我知道这个问题有点令人困惑,所以如果需要的话请随时要求澄清。
#include <vector>
#include <iostream>
using namespace std;
template <typename T, typename C>
struct MyClass {
// This doesnt work because of SFINAE
template <typename F, typename... A>
auto call_me(F func, A... args) { // lambda version
return func(args...);
}
template <typename R, typename F>
auto call_me(R C::* func) { // member function version
return (mContainer.*func);
}
C mContainer; // this is private in my actual code
};
int main() {
MyClass<int, std::vector<int> > test;;
// these two calls will call the member function version of the overload
cout << test.call_me(&std::vector<int>::size) << endl;
using insert_func_t = std::vector<int>::iterator(std::vector<int>::*)(std::vector<int>::const_iterator, const int&);
test.call_me(static_cast<insert_func_t>(&std::vector<int>::insert), test.mContainer.begin(), 4);
// this call will call the lambda version of the overload
cout << test.call_me([](std::vector<int>& in){ in.push_back(5); });
return 0;
}
'的std :: invoke'提供统一的调用语法。如果你还没有在标准库中使用它,它不需要编写C++ 17功能,而且现在有独立的实现。通过使用'invoke'函数,您不需要通过调用差异来污染其余的代码。 – chris
@克里斯我只是检查了这一点,但它仍然给我留下搞清楚,如果提供的参数是一个成员函数或它的一个可调用对象的问题。 – Aryan
@IgorTandetnik嗯,我有这个尝试也行,但它仍然无法正常工作的r(C :: * FUNC)()'和'用住宅(丙类:: * FUNC)(参数...)'用'Args'是基于您的代码的另一模板参数 – Aryan