c++ - std::is_base_of 和虚基类

标签 c++ c++11 enable-if

有没有办法判断一个基类是不是虚基类?

std::is_base_of 将标识一个基类,但我正在寻找类似 std::is_virtual_base_of 的东西来标识一个虚拟基类。

这是出于 SFINAE 的目的,我想在 std::is_virtual_base_of 为真时使用 dynamic_cast(性能较低),在它为假时使用 static_cast(性能更高)。

最佳答案

namespace details {
  template<template<class...>class, class, class...>
  struct can_apply:std::false_type {};
  template<class...>struct voider{using type=void;};
  template<class...Ts>using void_t=typename voider<Ts...>::type;
  template<template<class...>class Z, class... Ts>
  struct can_apply<Z, void_t<Z<Ts...>>, Ts...>:std::true_type {};
}
template<template<class...>class Z, class... Ts>
using can_apply = details::can_apply<Z, void, Ts...>;

这让我们可以轻松地在模板应用程序上进行模块化 SFINAE。

template<class Dest, class Src>
using static_cast_r = decltype(static_cast<Dest>( std::declval<Src>() ));
template<class Dest, class Src>
using can_static_cast = can_apply< static_cast_r, Dest, Src >;

现在我们可以确定是否可以静态转换。

现在我们实现它:

namespace details {
  template<class Dest, class Src>
  Dest derived_cast_impl( std::true_type /* can static cast */ , Src&& src )
  {
    return static_cast<Dest>(std::forward<Src>(src));
  }

  template<class Dest, class Src>
  Dest derived_cast_impl( std::false_type /* can static cast */ , Src&& src )
  {
    return dynamic_cast<Dest>(std::forward<Src>(src));
  }
}
template<class Dest, class Src>
Dest derived_cast( Src&& src ) {
  return details::derived_cast_impl<Dest>( can_static_cast<Dest, Src&&>{}, std::forward<Src>(src) );
}

测试代码:

struct Base { virtual ~Base() {} };

struct A : virtual Base {};
struct B : Base {};

struct Base2 {};
struct B2 : Base2 {};

int main() {
  auto* pa = derived_cast<A*>( (Base*)0 ); // static cast won't work
  (void)pa;
  auto* pb = derived_cast<B*>( (Base*)0 ); // either would work
  (void)pb;
  auto* pb2 = derived_cast<B2*>( (Base2*)0 ); // dynamic cast won't work
  (void)pb2;
}

live example

关于c++ - std::is_base_of 和虚基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45948835/

相关文章:

c++ - 如何将 std::enable_if 与自推断返回类型一起使用?

c++ - 从一对数组中获取匹配的元素 (C++/OpenCV)

c++ - 从 MAT 文件中读取 C 应用程序中的自定义类

c++ - 从 GridLayout 中删除单元格

最近的 MSVC 中的 C++ 模板解析错误,GCC、LLVM 和较旧的 MSVC 正常

c++11 - MSVC 中的 std::atomic<> 运算符++

c++ - 等待多个 future ?

使用概念具有特定值类型的任何容器的 C++ 迭代器

c++ - 为什么这不会将运算符重载标记为内联导致重复定义错误?

c++ - 使用带有匿名类型参数的 std::enable_if