У меня есть следующая схема:
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