2016-02-15 54 views
2

對不起我的問題有些複雜,那就是:<懸而未決的重載函數類型>使用成員函數指針和模板

我有認爲,聲明任何像這樣的非類型模板參數的輔助結構:

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

我用它來存儲成員函數指針,以便在編譯時使用。

然後,我有一個叫TestClass類,它具有一個typedef到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

非常感謝!

+0

請注意''方法'主要是'std :: integral_constant'。 對於第二條註釋行,您必須刪除'const':'std :: remove_const_t '。 – Jarod42

+0

其他錯誤可以簡化爲[Demo](http://coliru.stacked-crooked.com/a/0f78b09dc2924fa9)(*「模板參數t的無效顯式指定參數」*)。 – Jarod42

回答

0

我發現了這個錯誤。您不能將成員函數指針發送到存儲在變量中的模板參數,即使是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>); 
相關問題