簡體   English   中英

指向重載成員函數的指針的 C++ 模板參數推導

[英]C++ template argument deduction for pointers to overloaded member function

我目前正在研究處理指向成員函數的指針的模板函數。 它最初是這樣的:

template <typename C, typename RT, typename... P>
auto CreateTestSuite(RT(C::* pFunc)(P...))
{...}

但是,我很快發現,如果我嘗試將指向 const 成員函數的指針傳遞給它,模板將無法識別這一點。 所以我然后添加了這個重載版本:

template <typename C, typename RT, typename... P>
auto CreateTestSuite(RT(C::* pFunc)(P...) const)
{...}

對於分別具有 const 和非常量的兩個不同成員函數,它工作正常。 但是,如果我嘗試調用CreateTestSuite以獲得指向重載成員函數的指針,則會出現問題。

例如,假設我有以下 A 類:

class A
{
public:
    return_type test(...) {...}
    return_type test(...) const {...}
};

現在當我嘗試進行函數調用時

CreateTestSuite(&A::test);

編譯器將無法判斷我使用的是哪個重載版本。 此外,這個問題不能通過顯式指定模板參數來解決,因為它們對於CreateTestSuite的重載版本是相同的。

如何從兩個版本中明確選擇?

編輯:我可以接受對CreateTestSuite微小修改。

非常感謝。

您可以向CreateTestSuite()添加一個額外的模板bool來決定是否選擇const限定成員函數:

#include <type_traits>

template <bool IsConst = false, typename C, typename RT, typename... P>
auto CreateTestSuite(RT(C::* pFunc)(P...), std::enable_if_t<!IsConst>* = nullptr)
{ }

template <bool IsConst, typename C, typename RT, typename... P>
auto CreateTestSuite(RT(C::* pFunc)(P...) const, std::enable_if_t<IsConst>* = nullptr)
{ }

然后您可以顯式指定IsConst來調用CreateTestSuite()

CreateTestSuite(&A::test);
CreateTestSuite<true>(&A::test);
CreateTestSuite<false>(&A::test);

演示。

由於您的問題只是選擇正確的重載,您可以編寫助手:

template <typename C, typename RT, typename... P>
constexpr auto non_const_overload(RT (C::*pFunc)(P...)) { return pFunc; }

template <typename C, typename RT, typename... P>
constexpr auto const_overload(RT (C::*pFunc)(P...) const) { return pFunc; }

隨着使用

CreateTestSuite(non_const_overload(&A::test));
CreateTestSuite(const_overload(&A::test));

演示

注意:您可能需要 24 個助手來處理所有與volatile組合,參考 this 和 C-ellipsis。

或 MACRO(立即調用 c++20 lambda):

#define OVERLOAD(name, /*qualifiers*/...) []<typename C, typename RT, typename... P>(RT (C::*pFunc)(P...) __VA_ARGS__){ return pFunc; }(name)
CreateTestSuite(OVERLOAD(&A::test)); /*no const*/
CreateTestSuite(OVERLOAD(&A::test,)); /*no const*/
CreateTestSuite(OVERLOAD(&A::test, const));

演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM