Reputation: 288
class A
{
public:
A* m_child;
A* m_brother;
int x;
A(int num) :x{ num } {};
public:
template<typename Pred, typename...Args>
void ForFamily(Pred, Args&&... args) {
if (m_child) Pred(m_child*, std::forward<Args>(args)...);
if (m_brother) m_brother->Pred(std::forward<Args>(args)...);
}
void f(int a, int b) {
cout << x + a + b;
}
void g(int a) {
cout << a + x;
}
};
I wanna make a Template_Func that works for evey m_child and m_brother. How I can make this works? I gonna use it like this way
int main()
{
A a(1), b(2), c(3);
a.m_child = &b;
a.m_brother = &c;
a.ForFamily(A::f, 1, 2);
a.ForFamily(A::g, 1);
}
Upvotes: 0
Views: 77
Reputation: 82451
Use a member function pointer as the first parameter of the member function. Note that I also added default initializations to the pointers to avoid undefined behavior, if those members are not initialized:
class A
{
public:
A* m_child {nullptr};
A* m_brother {nullptr};
int x;
A(int num) :x{ num } {};
public:
template<typename... Args>
void ForFamily(void (A::*funct)(Args...), Args&&... args)
{
if (m_child != nullptr)
{
(m_child->*funct)(std::forward<Args>(args)...);
}
if (m_brother != nullptr)
{
(m_brother->*funct)(std::forward<Args>(args)...);
}
}
void f(int a, int b) {
cout << x + a + b;
}
void g(int a) {
cout << a + x;
}
};
int main()
{
A a(1), b(2), c(3);
a.m_child = &b;
a.m_brother = &c;
a.ForFamily(&A::f, 1, 2);
a.ForFamily(&A::g, 1);
}
You may want to place the functionality outside of class A
though, e.g.
template<typename Funct, typename... Args>
void ForFamily(Funct funct, Args&&... args)
{
if (m_child != nullptr)
{
funct(m_child->x, std::forward<Args>(args)...);
}
if (m_brother != nullptr)
{
funct(m_brother->x, std::forward<Args>(args)...);
}
}
...
a.ForFamily([](int x, int a, int b) { std::cout << (x + a + b);}, 1, 2);
a.ForFamily([](int x, int a) { std::cout << (x + a);}, 1);
or
template<typename Funct, typename... Args>
void ForFamily(Funct funct, Args&&... args)
{
if (m_child != nullptr)
{
funct(*m_child, std::forward<Args>(args)...);
}
if (m_brother != nullptr)
{
funct(*m_brother, std::forward<Args>(args)...);
}
}
...
a.ForFamily([](A& obj, int a, int b) { obj.f(a, b);}, 1, 2);
a.ForFamily([](A& obj, int a) { obj.g(a);}, 1);
since those are more flexible. (Note that if I had a real application using lambdas usually I wouldn't bother passing them though ForFamily
via forwarding but would simply bind/hardcode them to the lambda.)
Upvotes: 1