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