<未解析的重载函数类型> 带有成员函数指针和模板

Posted

技术标签:

【中文标题】<未解析的重载函数类型> 带有成员函数指针和模板【英文标题】:<unresolved overloaded function type> with member function pointer and templates 【发布时间】:2016-02-15 22:22:23 【问题描述】:

对不起,我的问题有点复杂,这里是:

我有一个辅助结构,它包含任何声明如下的非类型模板参数:

template<typename T, T t>
struct Method 
    using Type = T;
    constexpr static T method = t;
;

我用它来存储一个成员函数指针,以便在编译时使用。

然后,我有一个名为 TestClass 的类,它具有 Method 类型的 typedef,其中一个方法作为参数:

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

非常感谢!

【问题讨论】:

请注意,Method 主要是 std::integral_constant。对于第二条注释行,您必须删除 const : std::remove_const_t&lt;decltype(TestClass::MethodToCall::method)&gt; 其他错误可以简化为Demo ("invalid explicit-specified argument for template parameter t")。 【参考方案1】:

我发现了错误。您不能将成员函数指针发送到存储在变量中的模板参数,即使是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>);

【讨论】:

以上是关于<未解析的重载函数类型> 带有成员函数指针和模板的主要内容,如果未能解决你的问题,请参考以下文章

另一个类中使用的非静态类<未解析的重载函数类型>

错误:“int”和“<未解析的重载函数类型>”类型的无效操作数到二进制“operator/”

没有匹配的函数用于调用未解析的重载函数类型

运算符重载

C ++:类之间的“未解决的重载函数类型”

C++点滴----关于类常成员函数