编写自定义c ++ 14样式别名

时间:2015-09-23 18:22:31

标签: c++ templates alias c++14

我想为_t创建一个std::is_base_of别名,类似于std::enable_if_tstd::enable_if的别名的方式。所以我在标准标题中添加了以下内容:

namespace std {
  template<typename T, typename U>
  using is_base_of_t = typename is_base_of<T,U>::type;
}

我在以下上下文中使用了这个新别名:

template <typename SpaceT,
          typename TagT,
          typename = std::enable_if_t<std::is_base_of_t<Space,SpaceT>>>
class SpatialTree : public SpaceT {
};

我收到以下gcc错误:

SpatialTree.h:48:101: error: type/value mismatch at argument 1 in template parameter list for ‘template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type’
 template <typename SpaceT, typename TagT, typename = std::enable_if_t<std::is_base_of_t<Space,SpaceT>>>

我做错了什么?

3 个答案:

答案 0 :(得分:5)

std::enable_if因此被定义:

template< bool B, class T = void >
struct enable_if;

第一个参数是,而不是类型。您需要传入std::is_base_of<Space,SpaceT>::value作为第一个参数。使用C ++ 14,正确的别名将是变量模板:

template <class Base, class Derived>
constexpr bool is_base_of_v = std::is_base_of<Base, Derived>::value;

您使用相同的方式:

template <typename SpaceT, typename TagT,
          typename = std::enable_if_t<is_base_of_v<Space,SpaceT>>>
                                                ^^^
class SpatialTree : public SpaceT {
};

后者目前存在于<experimental/type_traits>

答案 1 :(得分:3)

enable_if[_t]想要bool作为其第一个参数。您必须撰写std::enable_if_t<std::is_base_of_t<Space,SpaceT>::value>std::enable_if_t<std::is_base_of_t<Space,SpaceT>{}>,否则您会传递需要bool的类型。

但是,您可能希望定义std::experimental::is_base_of_v的对应部分:

template <class Base, class Derived>
constexpr bool is_base_of_v = std::is_base_of<Base, Derived>{};

并用作std::enable_if_t<is_base_of_v<Space, SpaceT>>

也就是说,我不会在命名空间std中定义这些模板中的任何一个,因为它根据[namespace.std] / 1调用UB。

答案 2 :(得分:2)

从Clang 3.6和g ++ 5.1

开始提供
#include <experimental/type_traits>

using namespace std::experimental;

struct B {}; struct D : B {};

int main() 
{
    static_assert(is_base_of_v<B, D>, "");
}