AMDG
On 02/02/2018 12:13 PM, John Maddock via Boost wrote:
There is a problem with is_virtual_base_of in that it doesn't work
especially well - most of the time it works OK, but can be made to fail
catastrophically in a few situations, see for example:
https://svn.boost.org/trac10/ticket/11323
Now... it turns out that with C++14 and later we now have is_detected
which can test the validity of almost any expression... and I'm
wondering if there's a cunning way to press this into action to create a
more accurate is_virtual_base_of, but I'm having trouble coming up with
anything. Any bright ideas? Note that an explicit static_cast can't be
tested for, though we can use is_constructible if required.
Testing for static_cast(Base*) mostly
works, except for private (or protected) virtual inheritance.
#include
template
constexpr bool is_virtual_base_impl(...) { return true; }
template(std::declval()))>* =
nullptr>
constexpr bool is_virtual_base_impl(int) { return false; }
template
using is_virtual_base_of_t =
std::integral_constant<
bool,
std::is_base_of::value &&
is_virtual_base_impl(0) &&
!is_virtual_base_impl(0)
>;
#include <iostream>
class X { };
class Y : virtual public X {};
class Z : private X {};
class A : public X {};
class B : public X {};
class C : public A, public B {};
class D : private virtual X {};
class E : public virtual X {};
class F : public E, public Y {};
int main()
{
std::cout << is_virtual_base_of_t::value << std::endl; // true
std::cout << is_virtual_base_of_t::value << std::endl;
std::cout << is_virtual_base_of_t::value << std::endl;
std::cout << is_virtual_base_of_t::value << std::endl;
std::cout << is_virtual_base_of_t::value << std::endl;
std::cout << is_virtual_base_of_t::value << std::endl; // oops
std::cout << is_virtual_base_of_t::value << std::endl; // true
}
In Christ,
Steven Watanabe