繁体   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