Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Multiple pure virtual overrides from template parameter pack

7 views
Skip to first unread message

bitrex

unread,
Apr 20, 2019, 12:51:00 PM4/20/19
to
Is there a cleaner way to do this, where I have a Base class
with protected or private generic pure virtual function templated on
"Param", I have an interface class with a public interface to it, and
I have any number of variadic template implementation classes (Bar, in
this case) where I can declare multiple overrides for the pure virtual
function.

I have used the CRTP to "inject" the interface/forwarding template
expansion function in class "Base" here. but I'd prefer the virtual
function and overrides in Bar to be private but can't figure out how to
do that.

#include <utility>

template <typename Param>
class BaseSingle {
protected:
virtual void BaseFoo(Param) = 0;
};

template <typename Derived, typename... Params>
class Base : public BaseSingle<Params>... {
public:
template <typename T>
void Foo(T&& x) {

static_cast<Derived*>(this)->BaseSingle<T>::BaseFoo(std::forward<T>(x));
}
};

template <typename... Params>
class Bar : public Base<Bar<Params...>, Params...> {
protected:
void BaseFoo(int x) override {}
void BaseFoo(char x) override {}
};

int main() {
Bar<int, char> bar;
bar.Foo('a');
bar.Foo(42);
}

On Compiler Explorer for the MSP430 this compiles to (-std=c++11 -Os
-fno-rtti -fno-threadsafe-statics):

Bar<int, char>::BaseFoo(int):
PUSHM.W #1, R4
MOV.W R1, R4
POPM.W #1, r4
RET
Bar<int, char>::BaseFoo(char):
PUSHM.W #1, R4
MOV.W R1, R4
POPM.W #1, r4
RET
non-virtual thunk to Bar<int, char>::BaseFoo(char):
PUSHM.W #1, R4
MOV.W R1, R4
POPM.W #1, r4
RET
main:
PUSHM.W #1, R4
MOV.W R1, R4
SUB.W #4, R1
MOV.W #vtable for Bar<int, char>+4, -4(R4)
MOV.W #vtable for Bar<int, char>+12, -2(R4)
MOV.B #97, R13
MOV.W R4, R12
ADD.W #-2, R12
CALL #_ZN10BaseSingleIcE7BaseFooEc
MOV.B #6, R13
MOV.W R4, R12
ADD.W #-4, R12
CALL #_ZN10BaseSingleIiE7BaseFooEi
MOV.B #0, R12
ADD.W #4, R1
POPM.W #1, r4
RET
vtable for Bar<int, char>:
.short 0
.short 0
.short Bar<int, char>::BaseFoo(int)
.short Bar<int, char>::BaseFoo(char)
.short -2
.short 0
.short non-virtual thunk to Bar<int, char>::BaseFoo(char)

0 new messages