簡體   English   中英

將指向類的成員傳遞為模板參數

[英]Passing a pointer-to-class-member as a template parameter

我想編寫一個將進程應用於類成員的函數。 以下代碼正在運行:

class AA
{
public:
    AA(){};
    ~AA(){};
    std::string type="AA";
};

class BB
{
public:
    BB(){};
    ~BB(){};
    template <typename T, typename TT>
    void test(T& a, TT(T::*memberPtr))
    {
        std::cout<<"test: "<<(a.*memberPtr)<<std::endl;
    }
    std::string type="BB";
};

int main()
{
    AA a;
    BB b;
    b.test(a, &AA::type);
}

但是我在編譯時就知道了所有內容所以我想知道是否有可能寫出相同但只有模板的內容? 所以我可以這樣寫:

b.test<&AA::type>(a);

調用內部測試(a):

std::cout<<"test: "<< (a.*MEMBER) <<std::endl; // MEMBER is given in template

或類似的東西。

你不能只test<&AA::type> ,因為你還需要告訴函數模板你期望成員指向哪種類型的指針。 典型的模式是:

template <class M, M member, class T> // deduced go last
void test(T& a) {
    cout << (a.*member);
}

用法:

test<decltype(&AA::type), &AA::type>

我相信目前有一個減少那里的冗長的建議,但在那之前,它並不是世界上最糟糕的事情,你可以隨時:

#define TYPE_AND_VAL(foo) decltype(foo), foo
test<TYPE_AND_VAL(&AA::type)>

我提到的那個提議是在C ++ 17中,並允許你這樣做:

template <auto member, class T>
void test(T& a) {
    cout << (a.*member);
}

test<&AA::type>(a);

這與謝拉德的答案有關,但妥協是通過你的班級和一個lambda。 編譯器能夠內聯lambda,因此您可能不會在運行時為它付費:

struct BB
{
public:
    template <typename T, typename F>
    void test(T& a, F f)
    {
        std::cout<<"test: "<< f(a) <<std::endl;
    }
    std::string type="BB";
};

int main()
{
    AA a;
    BB b;
    b.test(a, [](AA& a){return a.type;});
}

您可能(或可能不)比使用指向類成員的指針更清楚。

只是消除這種有點強烈的類型。 而不是請求用戶為您提供類和成員poiner,只需接受模板化仿函數並調用它的operator()。 這將是最靈活和最簡潔的。

暫無
暫無

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

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