Sunday, September 1, 2019

c++ - How to derive from a nested class of a variadic template argument?



Given the following two structs, one could derive from both nested 'Nested' classes, and call foo() and bar() from the derived object:



struct WithNested1 {
template struct Nested {
void foo();
};

};

struct WithNested2 {
template struct Nested {
void bar();
};
};

struct Test : WithNested1::Nested,
WithNested2::Nested

{

};

Test test;
test.foo();
test.bar();



But, if both of the outer classes were passed as variadic template arguments, how would you derive from them?




For example, this fails to compile:



template
struct Test : Ts::template Nested...
{

};

Test test;

test.foo();
test.bar();



error: 'foo' : is not a member of 'Test'
error: 'bar' : is not a member of 'Test'




strangely, it compiles if the calls to foo() and bar() are removed.


Answer




template                                                           
struct Test : Ts::template Nested>...
{

};


This is the same answer as above but I figured I'd explain how it works. First in your example Test has no template param (which the compiler should warn you of), but which should we give it. The point of CRTP is to give the class you inherit from a template param that is the same as your type, that way it has access to your methods and members through the of the template param. Your type in this case is Test so that is what you have to pass it. As @aschepler already pointed out normally you could use Test by itself but it's not in scope until your already inside the class.



I think this is a cleaner way of doing what you want.




template                                                               
struct A {
void bar (){
static_cast(this)->val = 3;
}
};

template
struct B {

void foo (){
static_cast(this)->val = 90;
}
};


template class ... Ts>
struct Test : Ts>...
{
int val;

};

int main() {
Test test;
test.foo();
test.bar();
return 0;
}

No comments:

Post a Comment

hard drive - Leaving bad sectors in unformatted partition?

Laptop was acting really weird, and copy and seek times were really slow, so I decided to scan the hard drive surface. I have a couple hundr...