我試圖創建一個函數重載因此它只能結合(工程)成員函數。我接過來一看在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