编写自定义 c++14 风格的类型别名
Writing custom c++14-style type aliases
我想为 std::is_base_of
创建一个 _t
别名,类似于 std::enable_if_t
是 std::enable_if
的别名。所以我将以下内容添加到我的标准 header:
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>>>
我做错了什么?
std::enable_if
定义如下:
template< bool B, class T = void >
struct enable_if;
第一个参数是 值,不是类型。您需要传入 std::is_base_of<Space,SpaceT>::value
作为第一个参数。对于 C++14,正确的别名应该是 variable template:
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>
。
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
从 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>, "");
}
我想为 std::is_base_of
创建一个 _t
别名,类似于 std::enable_if_t
是 std::enable_if
的别名。所以我将以下内容添加到我的标准 header:
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>>>
我做错了什么?
std::enable_if
定义如下:
template< bool B, class T = void >
struct enable_if;
第一个参数是 值,不是类型。您需要传入 std::is_base_of<Space,SpaceT>::value
作为第一个参数。对于 C++14,正确的别名应该是 variable template:
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>
。
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.
从 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>, "");
}