I have the following scheme:
struct Baz {};
struct Qux {};
struct Base {
virtual ~Base() {}
virtual void foo() = 0;
};
template<typename T> struct Identity { static bool const value = false; };
template<typename T> void bar(T) { static_assert(Identity<T>::value, "Busted!!!"); }
template<> void bar<Baz>(Baz) {}
template<typename T>
struct Derived : Base {
T m;
void foo() { bar(m); }
};
int main() {
Base *b0 = new Derived<Baz>;
b0->foo();
Base *b1 = new Derived<Qux>;
(void) b1;
}
That is, I have a pure virtual class Base and a template class Derived that inherits from Base and overrides the pure virtual function foo as required. Now, inside foo I call function template bar. bar has a specialization for class Baz but not for class Qux. When in main I'm trying to materialize an object of Derived<Baz> everything's OK. But when I try to materialize an object of Derived<Qux> compiler hits static_assert.
Q:
Is there a way to transform my code in such a way that compiler will hit static assert in Derived<Qux> only if Derived<Qux>::foo() is called.
That is, materializing an object of Derived<Qux> will pass:
Base *b1 = new Derived<Qux>;
But when later in code the programmer tries to call:
b1->foo(); // compile error static assert