【问题标题】:Constraining a specialised class template parameter to integer and floating point将专用类模板参数约束为整数和浮点
【发布时间】:2020-08-21 14:22:52
【问题描述】:

我想创建一个专业化的类专业化 所有整数类型,另一个用于所有浮点类型,另一个用于布尔类型,以及 所有其他人都为我自己的类型,并且无法与其他任何人一起编译。

我希望整数用于 {signed or unsigned} * {short, int, long or long long}。 包含 char 是不可取的,但我可以忍受它。浮点 适用于 float、double 和 long double。

struct MyClass { /* ... */ };

template <class x> struct Specialise;

template <> struct Specialise <bool>    { /* ... */ };
template <> struct Specialise <int>     { /* for short, int, long ... */ };
template <> struct Specialise <double>  { /* for float, double, long double */ };
template <> struct Specialise <MyClass> { /* ... */ };

我尝试过使用以下变体:-

template <typename x,typename=typename std::enable_if<std::is_integral<x>::value,x>::type>

但是编译器告诉我我一直弄错了。请问正确的语法是什么?

(我正在使用 C++14,但也许能够升级到 17。没有机会进行实验性 20。)

【问题讨论】:

标签: c++ templates


【解决方案1】:

您可以为整数类型和浮点类型定义部分特化

// primary template
template <typename x, typename = void> 
struct Specialise;

// partial specialization for integer types
template <typename x>
struct Specialise <x, typename std::enable_if<std::is_integral<x>::value>::type> {}

// partial specialization for float-pointer types
template <typename x>
struct Specialise <x, typename std::enable_if<std::is_floating_point<x>::value>::type> {}

并为您展示的boolMyClass 定义完全专业化;当给定完全相同的类型时,它们更倾向于部分专业化。

【讨论】:

    【解决方案2】:

    你需要一个职业专长。可以使用 enable_if ,示例如下。这是 C++17 版本,对于 C++14,只需将 _v 替换为 ::value

    需要对 bool 进行特殊检查,因为 is_integral_v 也会为 bool 返回 true。

    #include <type_traits>
    
    struct MyClass { /* ... */ };
    
    template <class x, class Enable=void> 
    struct Specialise;
    
    template <class T> 
    struct Specialise<T, typename std::enable_if_t<std::is_integral_v<T> && std::is_same_v<T, bool>>> 
    { /* for bool */ };
    
    template <class T> 
    struct Specialise<T, typename std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>>>     
    { /* for short, int, long ... */ };
    
    template <class T> 
    struct Specialise<T, typename std::enable_if_t<std::is_floating_point_v<T>>>    
    { /* for float, double, long double */ };
    
    template <class T> 
    struct Specialise<T, typename std::is_same<T,MyClass>>
    { /* for MyClass */ };
    

    【讨论】:

      猜你喜欢
      • 2014-03-25
      • 2022-01-22
      • 2021-09-04
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 2021-03-08
      • 1970-01-01
      相关资源
      最近更新 更多