Нет, виртуальная функция не помогает, так как вы меняете ее подпись.Вот возможная реализация, основанная на возможностях C ++ 11.Он правильно определяет функцию с необходимой подписью.
#include <type_traits>
template<typename, typename T>
struct has_doSth {
static_assert(
std::integral_constant<T, false>::value,
"Second template parameter needs to be of function type.");
};
// specialization that does the checking
template<typename C, typename Arg>
struct has_doSth<C, void(Arg)> {
private:
template<typename T>
static constexpr auto check(T*)
-> typename
std::is_same<
decltype( std::declval<T>().doSth( std::declval<Arg>()) ),
void
>::type; // attempt to call it and see if the return type is correct
template<typename>
static constexpr std::false_type check(...);
typedef decltype(check<C>(0)) type;
public:
static constexpr bool value = type::value;
};
template<typename T>
class Base {
public:
Base() {
static_assert(has_doSth<T, void(const T&)>::value, "Missing required function in the derived class.");
}
};
Использование:
class WellDerived : public Base<WellDerived> {
public:
void doSth(const WellDerived& d){
...
}
};
class BadDerived : public Base<BadDerived> {
public:
void doSth(int d){
...
}
};