template<typename T, typename F, typename ...Args>
auto f(F h, Args&&... args) -> decltype(h(args...)) {
T* t = new T(); // Don't worry, my actual code doesn't do this
return (t->h)(args...);
}
struct G {
int g() {
return 5;
}
};
int main() {
int k = f<G>(&G::g);
}
Microsoft 的编译器说 error C2672: 'f': no matching overloaded function found
和 error C2893: Failed to specialize function template 'unknown-type f(F,Args &&...)'
.
Clang 的编译器说 note: candidate template ignored: substitution failure [with T = G, F = int (G::*)(), Args = <>]: called object type 'int (G::*)()' is not a function or function pointer
和 error: no matching function for call to 'f'
.
我很确定int (G::*)()
是一个函数指针...?我错过了什么? (在我添加返回类型之前,所有这些都工作正常。)
最佳答案
I'm pretty sure
int (G::*)()
is a function pointer ... ? What am I missing?
不完全是:int (G::*)()
是指向非静态方法的指针。这不是完全相同的东西,需要一些不同的语法来调用它。
所以,而不是
return (t->h)(args...);
你应该添加一个*
并调用h()
如下
return (t->*h)(args...);
// ........^ add this *
decltype()
也是错误的。如果您至少可以使用 C++14,则可以避免使用它而只需使用 auto
作为返回类型
template <typename T, typename F, typename ...Args>
auto f (F h, Args&&... args) {
T* t = new T();
return (t->*h)(args...);
}
否则,如果你必须使用C++11,你可以包括<utility>
并使用 std::declval()
如下
template <typename T, typename F, typename ...Args>
auto f(F h, Args&&... args) -> decltype((std::declval<T*>()->*h)(args...)) {
T* t = new T(); // .................^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return (t->*h)(args...);
}
但是还有另一种方式来写你的f()
功能:推导返回的类型(因此避免了 auto
、 decltype()
和 std::declval()
)和 h()
的参数
你可以写f()
如下
template<typename R, typename T, typename ... As1, typename ... As2>
R f(R(T::*h)(As1...), As2 && ... args) {
T* t = new T();
return (t->*h)(args...);
}
并且您避免显式显示 G
输入调用它
int k = f(&G::g);
// .....^^^^^^^^ no more explicit <G> needed
因为 T
模板类型是从参数 &G::g
推导出来的.
关于c++ - 使用返回类型调用模板化成员指针函数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55067069/