I tried to make a traits to find if a method is virtual
: (https://ideone.com/9pfaCZ)
// Several structs which should fail depending if T::f is virtual or not.
template <typename T> struct Dvf : T { void f() final; };
template <typename T> struct Dvo : T { void f() override; };
template <typename T> struct Dnv : T { void f() = delete; };
template <typename U>
class has_virtual_f
{
private:
template <std::size_t N> struct helper {};
template <typename T>
static std::uint8_t check(helper<sizeof(Dvf<T>)>*);
template<typename T> static std::uint16_t check(...);
public:
static
constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
};
Test cases:
struct V { virtual void f(); };
struct NV { void f(); };
struct E { };
struct F { virtual void f() final; }; // Bonus (unspecified expected output)
static_assert( has_virtual_f< V>::value, "");
static_assert(!has_virtual_f<NV>::value, "");
static_assert(!has_virtual_f< E>::value, "");
But I got error: 'void Dvf<T>::f() [with T = NV]' marked final, but is not virtual
.
If I don't use sizeof
and directly Dvf<T>*
in check
, I don't have compilation error, but check
is not discarded for "bad" type in SFINAE :( .
What is the proper way to detect if a method is virtual
?
sizeof(Dvf<T>)
instantiatesDvf<T>
whereasDvf<T>*
does not. You cannot instantiate an invalid class during a SFINAE test or you'll get an error. As for a proper way, don't know if possible; trying. – Nostology