#include <iostream>
#include <vector>
using namespace std;
struct TaskInterface {
virtual void Do( ) = 0 ;
virtual ~TaskInterface( ) { }
} ;
template < class Impl>
class TaskBase
: public TaskInterface {
virtual void Do( ) {
DoDerivedImpl( ) ;
}
private :
void DoDerivedImpl( ) {
static_cast < Impl* > ( this ) - > DoImpl( ) ;
}
void DoImpl( ) {
// Issue a static_assert error here, that there's no appropriate overridden
// implementation of DoImpl() available:
static_assert( static_cast < Impl* > ( this ) - > DoImpl ! = TaskBase< Impl> :: DoImpl , "TaskBase requires an appropriate implementation of DoImpl()" ) ;
}
} ;
class TaskType1 : public TaskBase< TaskType1> {
public :
void DoImpl( ) {
cout << "TaskType1::DoImpl()" << endl;
}
} ;
class TaskType2 : public TaskBase< TaskType2> {
public :
void DoImpl( ) {
cout << "TaskType2::DoImpl()" << endl;
}
} ;
class TaskType3 : public TaskBase< TaskType3> {
} ;
int main( ) {
std:: vector < TaskInterface* > tasks;
TaskType1 t1;
TaskType2 t2;
TaskType3 t3;
tasks.push_back ( & t1) ;
tasks.push_back ( & t2) ;
tasks.push_back ( & t3) ;
for ( std:: vector < TaskInterface* > :: iterator it = tasks.begin ( ) ;
it ! = tasks.end ( ) ;
++ it) {
( * it) - > Do( ) ;
}
}
CSNpbmNsdWRlIDxpb3N0cmVhbT4KCSNpbmNsdWRlIDx2ZWN0b3I+Cgl1c2luZyBuYW1lc3BhY2Ugc3RkOwoKICAgIHN0cnVjdCBUYXNrSW50ZXJmYWNlIHsKICAgICAgICB2aXJ0dWFsIHZvaWQgRG8oKSA9IDA7CiAgICAgICAgdmlydHVhbCB+VGFza0ludGVyZmFjZSgpIHt9CiAgICB9OwoKICAgIHRlbXBsYXRlPGNsYXNzIEltcGw+CiAgICBjbGFzcyBUYXNrQmFzZSAKICAgIDogcHVibGljIFRhc2tJbnRlcmZhY2UgewogICAgICAgIHZpcnR1YWwgdm9pZCBEbygpIHsKICAgICAgICAgICAgRG9EZXJpdmVkSW1wbCgpOwogICAgICAgIH0KICAgIHByaXZhdGU6CiAgICAgICAgdm9pZCBEb0Rlcml2ZWRJbXBsKCkgewogICAgICAgICAgICBzdGF0aWNfY2FzdDxJbXBsKj4odGhpcyktPkRvSW1wbCgpOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBEb0ltcGwoKSB7CiAgICAgICAgICAgICAvLyBJc3N1ZSBhIHN0YXRpY19hc3NlcnQgZXJyb3IgaGVyZSwgdGhhdCB0aGVyZSdzIG5vIGFwcHJvcHJpYXRlIG92ZXJyaWRkZW4KICAgICAgICAgICAgIC8vIGltcGxlbWVudGF0aW9uIG9mIERvSW1wbCgpIGF2YWlsYWJsZToKICAgICAgICAgICAgIHN0YXRpY19hc3NlcnQoc3RhdGljX2Nhc3Q8SW1wbCo+KHRoaXMpLT5Eb0ltcGwgIT0gVGFza0Jhc2U8SW1wbD46OkRvSW1wbCwgIlRhc2tCYXNlIHJlcXVpcmVzIGFuIGFwcHJvcHJpYXRlIGltcGxlbWVudGF0aW9uIG9mIERvSW1wbCgpIik7CiAgICAgICAgfQogICAgfTsKICAgIAogICAgY2xhc3MgVGFza1R5cGUxIDogcHVibGljIFRhc2tCYXNlPFRhc2tUeXBlMT4gewogICAgcHVibGljOgogICAgICAgIHZvaWQgRG9JbXBsKCkgewogICAgICAgICAgICBjb3V0IDw8ICJUYXNrVHlwZTE6OkRvSW1wbCgpIiA8PCBlbmRsOwogICAgICAgIH0KICAgIH07CgogICAgY2xhc3MgVGFza1R5cGUyIDogcHVibGljIFRhc2tCYXNlPFRhc2tUeXBlMj4gewogICAgcHVibGljOgogICAgICAgIHZvaWQgRG9JbXBsKCkgewogICAgICAgICAgICBjb3V0IDw8ICJUYXNrVHlwZTI6OkRvSW1wbCgpIiA8PCBlbmRsOwogICAgICAgIH0KICAgIH07CgogICAgY2xhc3MgVGFza1R5cGUzIDogcHVibGljIFRhc2tCYXNlPFRhc2tUeXBlMz4gewogICAgfTsKCglpbnQgbWFpbigpIHsKCSAgICBzdGQ6OnZlY3RvcjxUYXNrSW50ZXJmYWNlKj4gdGFza3M7CgkgICAgVGFza1R5cGUxIHQxOwoJICAgIFRhc2tUeXBlMiB0MjsKCSAgICBUYXNrVHlwZTMgdDM7CgkgICAgdGFza3MucHVzaF9iYWNrKCZ0MSk7CgkgICAgdGFza3MucHVzaF9iYWNrKCZ0Mik7CgkgICAgdGFza3MucHVzaF9iYWNrKCZ0Myk7CgkgICAgCgkgICAgZm9yKHN0ZDo6dmVjdG9yPFRhc2tJbnRlcmZhY2UqPjo6aXRlcmF0b3IgaXQgPSB0YXNrcy5iZWdpbigpOwoJICAgICAgICBpdCAhPSB0YXNrcy5lbmQoKTsKCSAgICAgICAgKytpdCkgewoJICAgICAgICAJKCppdCktPkRvKCk7CiAgICAgICAgfQoJfQ==
compilation info
prog.cpp: In instantiation of ‘void TaskBase<Impl>::DoImpl() [with Impl = TaskType3]’:
prog.cpp:18:13: required from ‘void TaskBase<Impl>::DoDerivedImpl() [with Impl = TaskType3]’
prog.cpp:14:27: required from ‘void TaskBase<Impl>::Do() [with Impl = TaskType3]’
prog.cpp:59:2: required from here
prog.cpp:24:61: error: invalid use of member function (did you forget the ‘()’ ?)
static_assert(static_cast<Impl*>(this)->DoImpl != TaskBase<Impl>::DoImpl, "TaskBase requires an appropriate implementation of DoImpl()");
^
prog.cpp:24:61: error: invalid use of member function (did you forget the ‘()’ ?)
stdout