在某些枚举的模板情况下启用类构造函数

拉雷基

出于性能原因,我使用带有枚举的模板化类,而不是继承继承(这不是一种选择)。

在这一点上,我有这样的事情:

typedef enum { A, B, C, D } QueueType;

template <QueueType T> class Queue {
    Queue(int a){...} // only usable when T = A
    Queue(unsigned a, unsigned b){...} // only usable when T = B || T = C
    Queue(somestruct z){...} // only usable when T = B || T = C
    //other constructors
}

现在,如果为defineT调用了不兼容的构造函数,我会使用大量烦人的ifs / switches和上升异常T

我想要使​​用std::enable_if或等效的方法来防止在构造函数上引发异常并在编译时检测此类错误。

我已经尝试了很多堆栈溢出和外部站点的std::enable_if示例,但是我几乎无法理解我在做什么,而且我总是以编译错误告终。

在此先感谢您,并很抱歉提出一个可能很简单的问题。我对模板没有知识。

环境:Linux GCC 8和c ++ 14限制:在没有虚拟方法的情况下可实现最佳性能。

最高66

我想要的是使用std :: enable_if或等效方法来防止在构造函数上引发异常并在编译时检测此类错误。

我已经尝试了很多堆栈溢出和外部站点的std::enable_if示例,但是我几乎无法理解我在做什么,而且我总是以编译错误告终。

问题std::enable_if(以及SFINAE,更笼统地说)是它只能检查模板参数。因此,可以通过对类的模板参数进行测试来启用/禁用完整的类,但是不能通过对类的模板参数进行测试来启用/禁用单个方法。

如果要SFINAE启用/禁用方法(如构造函数),则必须使其成为模板方法并测试该方法本身的模板参数。

所以你不能这样写

template <typename = std::enable_if_t<T == A>>
Queue (int)
 { } // only usable when T = A

因为它T是类的模板参数,而不是构造函数的模板参数。

但是有个窍门:您可以为模板参数使用默认值/类型;所以下面的代码有效

template <QueueType U = T, typename = std::enable_if_t<U == A>>
Queue (int)
 { } // only usable when T = A 

因为检查了U作为构造函数的模板参数的值

要仅在TisB时启用第二个构造函数C,您可以编写

template <QueueType U = T, typename = std::enable_if_t<(U == B) || (U == C)>> 
Queue (unsigned, unsigned)
 { } // only usable when T = B || T = C

以下是完整的编译示例

#include <type_traits>

typedef enum { A, B, C, D } QueueType;

template <QueueType T>
struct Queue
 {
   template <QueueType U = T, typename = std::enable_if_t<U == A>>
   Queue (int)
    { } // only usable when T = A

   template <QueueType U = T, typename = std::enable_if_t<(U == B) || (U == C)>>
   Queue (unsigned, unsigned)
    { } // only usable when T = B || T = C
 };

int main()
 {
   Queue<A>  qa0{1};         // compile
   //Queue<A>  qa1{1u, 2u};  // compilation error

   // Queue<B>  qb0{1};      // compilation error
   Queue<B>  qb1{1u, 2u};    // compile

   // Queue<C>  qc0{1};      // compilation error
   Queue<C>  qc1{1u, 2u};    // compile

   // Queue<D>  qd0{1};      // compilation error
   // Queue<D>  qd1{1u, 2u}; // compilation error
 }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

基类构造函数在未指定的情况下运行

如何在没有默认构造函数的情况下实现抽象类的Decorator类?

在没有公共构造函数的情况下实例化.NET类

在没有构造函数的情况下初始化const c ++类

在没有无参数构造函数的情况下序列化ISerializable类

C ++类:在没有构造函数重载的情况下初始化属性

在没有限定的情况下从 T 构造函数调用 T 类的纯虚拟实现?

C ++的类变量可以在没有Java构造函数的情况下初始化吗?

在没有构造函数声明类主体状态的情况下做出反应

NgXs:TypeError:类构造函数 MyState 不能在没有“new”的情况下被调用

默认情况下,案例类构造函数参数是否为公共val字段?

如何在不调用Java构造函数的情况下继承类

C ++类是否具有默认构造函数?在以下情况下会调用什么构造函数?

Noexcept对派生类构造函数的承诺:可以在不对基础构造函数作出诺言的情况下使用吗?

如何在不使用显式的情况下安全地允许单参数模板化构造函数?

在某些情况下,空类是否是正确的选择?

如何在不强制转换或复制签名的情况下使基类模板函数对派生类实例可见?

默认情况下,构造函数是公共的吗?

默认情况下继承构造函数noexcept(true)吗?

在没有构造函数的情况下反应定义状态

在多参数情况下使用转换构造函数

默认情况下应调用Move构造函数

Flutter 构造函数在没有 @ 的情况下显示错误

JS函数-数学优化,在某些情况下减1

在某些情况下允许从constexpr调用非constexpr函数

可变参数函数在某些情况下认为顺序错误

为什么项目可以在没有工厂的情况下创建带有构造函数参数的ViewModel类的实例

在没有构造函数的情况下将数据传递给ES7中的类

为什么超类为空的构造函数是必需的,而在可怕的菱形情况下却没有调用?