<unresolved overloaded function type> 带有成员函数指针和模板
<unresolved overloaded function type> with member function pointer and templates
抱歉我的问题有点复杂,这里是:
我有一个辅助结构,它包含任何非类型模板参数,声明如下:
template<typename T, T t>
struct Method {
using Type = T;
constexpr static T method = t;
};
我用它来存储一个成员函数指针,以便在编译时使用。
然后,我有一个名为 TestClass
的 class,它有一个 Method
类型的类型定义,其中一个方法作为参数:
struct TestClass {
void setFoo(int n) {}
using MethodToCall = Method<decltype(&TestClass::setFoo), &TestClass::setFoo>;
};
此时一切正常,我可以这样称呼它:
(tc.*TestClass::MethodToCall::method)(6); // compiles and runs
然后,问题来了:我有另一个成员函数再次将方法作为模板参数,我正试图从中获取一个指针。只有当我直接放置函数指针时它才有效。
struct Caller {
template<typename T, T t>
void callme(TestClass& test) {
(test.*t)(6);
}
};
template<typename F, typename T, typename... Args>
auto call(F f, T t, Args&&... args) -> decltype((t.*f)(std::forward<Args>(args)...)) {
(t.*f)(std::forward<Args>(args)...);
}
int main() {
Caller c;
TestClass tc;
(tc.*TestClass::MethodToCall::method)(6);
//call(&Caller::callme<TestClass::MethodToCall::Type, TestClass::MethodToCall::method>, c, tc);
call(&Caller::callme<decltype(&TestClass::setFoo), &TestClass::setFoo>, c, tc);
return 0;
}
前三个调用都不行。为什么是这样?我该如何解决?
如果我取消注释第一个调用,编译会给我这个错误:
main.cpp: In function 'int main()':
main.cpp:40:96: error: no matching function for call to 'call(<unresolved overloaded function type>, Caller&, TestClass&)'
call(&Caller::callme<TestClass::MethodToCall::Type, TestClass::MethodToCall::method>, c, tc);
^
main.cpp:30:6: note: candidate: template<class F, class T, class ... Args> decltype (call::t.*call::f((forward<Args>)(call::args)...)) call(F, T, Args&& ...)
auto call(F f, T t, Args&&... args) -> decltype((t.*f)(std::forward<Args>(args)...)) {
^
main.cpp:30:6: note: template argument deduction/substitution failed:
main.cpp:40:96: note: couldn't deduce template parameter 'F'
call(&Caller::callme<TestClass::MethodToCall::Type, TestClass::MethodToCall::method>, c, tc);
^
完整代码可以在这里找到:http://coliru.stacked-crooked.com/a/821c5b874b45ffb9
非常感谢!
我发现错误了。您不能将成员函数指针发送到存储在变量中的模板参数,即使是 constexpr
一个。
constexpr auto theMethod = &TestClass::setFoo;
// won't work
call(&Caller::callme<decltype(theMethod), theMethod>);
作为成员函数指针的模板参数,要求直接写成:
constexpr auto theMethod = &TestClass::setFoo;
// won't work
call(&Caller::callme<decltype(theMethod), &TestClass::setFoo>);
我的解决方案是传递一个 std::integral_constant
而不是直接传递函数指针。
using methodType = std::integral_constant<decltype(&TestClass::setFoo), &TestClass::setFoo>;
call(&Caller::callme<methodType>);
抱歉我的问题有点复杂,这里是:
我有一个辅助结构,它包含任何非类型模板参数,声明如下:
template<typename T, T t>
struct Method {
using Type = T;
constexpr static T method = t;
};
我用它来存储一个成员函数指针,以便在编译时使用。
然后,我有一个名为 TestClass
的 class,它有一个 Method
类型的类型定义,其中一个方法作为参数:
struct TestClass {
void setFoo(int n) {}
using MethodToCall = Method<decltype(&TestClass::setFoo), &TestClass::setFoo>;
};
此时一切正常,我可以这样称呼它:
(tc.*TestClass::MethodToCall::method)(6); // compiles and runs
然后,问题来了:我有另一个成员函数再次将方法作为模板参数,我正试图从中获取一个指针。只有当我直接放置函数指针时它才有效。
struct Caller {
template<typename T, T t>
void callme(TestClass& test) {
(test.*t)(6);
}
};
template<typename F, typename T, typename... Args>
auto call(F f, T t, Args&&... args) -> decltype((t.*f)(std::forward<Args>(args)...)) {
(t.*f)(std::forward<Args>(args)...);
}
int main() {
Caller c;
TestClass tc;
(tc.*TestClass::MethodToCall::method)(6);
//call(&Caller::callme<TestClass::MethodToCall::Type, TestClass::MethodToCall::method>, c, tc);
call(&Caller::callme<decltype(&TestClass::setFoo), &TestClass::setFoo>, c, tc);
return 0;
}
前三个调用都不行。为什么是这样?我该如何解决? 如果我取消注释第一个调用,编译会给我这个错误:
main.cpp: In function 'int main()':
main.cpp:40:96: error: no matching function for call to 'call(<unresolved overloaded function type>, Caller&, TestClass&)'
call(&Caller::callme<TestClass::MethodToCall::Type, TestClass::MethodToCall::method>, c, tc);
^
main.cpp:30:6: note: candidate: template<class F, class T, class ... Args> decltype (call::t.*call::f((forward<Args>)(call::args)...)) call(F, T, Args&& ...)
auto call(F f, T t, Args&&... args) -> decltype((t.*f)(std::forward<Args>(args)...)) {
^
main.cpp:30:6: note: template argument deduction/substitution failed:
main.cpp:40:96: note: couldn't deduce template parameter 'F'
call(&Caller::callme<TestClass::MethodToCall::Type, TestClass::MethodToCall::method>, c, tc);
^
完整代码可以在这里找到:http://coliru.stacked-crooked.com/a/821c5b874b45ffb9
非常感谢!
我发现错误了。您不能将成员函数指针发送到存储在变量中的模板参数,即使是 constexpr
一个。
constexpr auto theMethod = &TestClass::setFoo;
// won't work
call(&Caller::callme<decltype(theMethod), theMethod>);
作为成员函数指针的模板参数,要求直接写成:
constexpr auto theMethod = &TestClass::setFoo;
// won't work
call(&Caller::callme<decltype(theMethod), &TestClass::setFoo>);
我的解决方案是传递一个 std::integral_constant
而不是直接传递函数指针。
using methodType = std::integral_constant<decltype(&TestClass::setFoo), &TestClass::setFoo>;
call(&Caller::callme<methodType>);