У меня есть следующая схема:
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;
}
То есть, у меня есть чистый виртуальный класс Base и класс шаблона Derived, который наследует от Base и переопределяет чистую виртуальную функцию foo по мере необходимости. Теперь внутри foo я вызываю шаблон функции bar. bar имеет специализацию для класса Baz, но не для класса Qux. Когда в main, я пытаюсь материализовать объект Derived<Baz> все ОК. Но когда я пытаюсь материализовать объект Derived<Qux>, компилятор обращается к static_assert.
Q
Есть ли способ преобразовать мой код таким образом, чтобы компилятор попадал в static assert в Derived<Qux>, только если вызывается Derived<Qux>::foo().
То есть материализация объекта Derived<Qux> будет проходить:
Base *b1 = new Derived<Qux>;
Но когда позже в коде программист пытается вызвать:
b1->foo(); // compile error static assert