Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to take template mixin as argument?

Considering a C++ template mixin structure, how can I write a function that takes a mixin with a specific component? In this example, how can I give withAandB to worksWithA()?

struct Base {};

template <class T>
struct HasA : T
{
    int A;
};

template <class T>
struct HasB : T
{
    int B;
};

void WorksWithA(HasA<Base> &p)
{
    p.A++;
}

void WorksWithAandB(HasA<HasB<Base> > &p)
{
    p.A++;
    p.B++;
}

int _tmain(int argc, _TCHAR *argv[])
{
    HasA<Base> withA;
    HasA<HasB<Base> > withAandB;

    WorksWithA(withA); // OK
    WorksWithAandB(withAandB); // OK
    WorksWithA(withAandB); // KO, no conversion available

    return 0;
}

Even putting aside the construction problem, or mixin ordering (HasA<HasB<Base>> vs HasB<HasA<Base>>), I can't see a good way to write this function, beside making it a template too.

I'm currently in an environment without C++11, but I'd be interested if modern C++ provides a solution to this.

Thanks a lot!

like image 513
plule Avatar asked Feb 06 '23 09:02

plule


2 Answers

You can make the WorksWithA a template function which accepts any class wrapped with HasA:

template<typename T>
void WorksWithA(HasA<T> &p)
{
  p.A++;
}

In this case your code compiles with no errors.

like image 183
alexeykuzmin0 Avatar answered Feb 24 '23 01:02

alexeykuzmin0


I think you have to make your functions template as well?

template <class T>
void WorksWithA(HasA<T> &p)
{
    p.A++;
}

template <class T>
void WorksWithAandB(HasA<HasB<T> > &p)
{
    p.A++;
    p.B++;
}

Since HasA<HasB<Base>> is no way convertible to HasA<Base>.

like image 28
Marson Mao Avatar answered Feb 24 '23 01:02

Marson Mao