根据特定成员是否存在专门化模板 [英] Specialize template based on whether a specific member exists

查看:39
本文介绍了根据特定成员是否存在专门化模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个返回给定类型的整数类型(float、int、char...)的特征.基础是:

I want to write a trait that returns the integral type (float, int, char...) of a given type. Base is:

template< class T, typename T_SFINAE = void >
struct IntegralType;

template< class T >
struct IntegralType< T, std::enable_if< (std::is_integral<T>::value || std::is_floating_point<T>::value) > >{
  using type = T;
}

template< class T >
struct IntegralType<T>: IntegralType<T::type>{}

而且我希望它返回双倍:

And I want it to return double for:

struct foo{
  using type = double;
}
struct bar{
  using type = foo;
}

IntegralType<double>::type == double
IntegralType<foo>::type == double
IntegralType<bar>::type == double

这不起作用.我必须像这样合并第一个和第二个声明:

This does not work. I have to merge the first and 2nd declaration like that:

template< typename T, bool isIntegral = (std::is_integral<T>::value || std::is_floating_point<T>::value) >
struct IntegralType{
    using type = T;
};

template< typename T >
struct IntegralType< T, false >: IntegralType< typename T::type >{};

但是现在,如果我的库的用户的类型的成员名为MyType"而不是type"怎么办?我如何才能将其专门用于以下结构:

But what now, if a user of my library has types with members named "MyType" instead of "type"? How could I make it possible to specialize this on structs like:

struct foobar{
  using MyType = double;
}

这甚至可能吗?实际上看起来它应该与 SFINAE 一起使用

Is this even possible? Actually looks like it should work with SFINAE

推荐答案

您可以使用 void_t:

You can do this using void_t:

//void_t for evaluating arguments, then returning void
template <typename...>
struct voider { using type = void; };
template <typename... Ts>
using void_t = typename voider<Ts...>::type;

//fallback case, no valid instantiation
template< class T, typename T_SFINAE = void >
struct IntegralType;

//enabled if T is integral or floating point
template< class T >
struct IntegralType< T, std::enable_if_t< (std::is_integral<T>::value || std::is_floating_point<T>::value) > >{
  using type = T;
};

//enabled if T has a ::type member alias
template< class T >
struct IntegralType<T, void_t<typename T::type>> : IntegralType<typename T::type>{};

//enabled if T has a ::MyType member alias
template< class T >
struct IntegralType<T, void_t<typename T::MyType>> : IntegralType<typename T::MyType>{};

这篇关于根据特定成员是否存在专门化模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆