繁体   English   中英

条件类模板构造函数

[英]Conditional class template constructor

我试图使一个具有条件成员的类如下(示例代码来说明问题):

template<bool b>
struct conditional_members {};

template<>
struct conditional_members<true> 
{ int m; };

template<typename T, bool b>
struct my_class : public conditional_members<b>
{
    T n;

    // constructor for case when b is false
    my_class(T n) : n(n) {};

    // constructor for case when b is true
    my_class(T n, int m) : n(n), m(m) {};
};

我需要根据bool b有两个条件构造函数,但这不能编译。 我试着用bool值专门化构造函数:

template<typename T>
my_class<T, true>::my_class(T n, int m) : n(n), m(m) {};

template<typename T>
my_class<T, false>::my_class(T n) : n(n) {};

但这不能编译,因为不允许部分函数模板专门化。

有没有办法做到这一点?

问题所在

// constructor for case when b is true
my_class(T n, int m) : n(n), m(m) {};

是构造函数的mem-initializer-list只能命名虚拟基类,直接基类和直接非静态数据成员,而不能命名像m这样的继承成员。 这是因为基类的成员是由基类子对象构造函数初始化的,因此无法再次初始化(尽管可以对其进行分配)。

您可以改为指定基类初始化程序。 在此示例中, conditional_members是一个聚合,因此聚合初始化将起作用:

// constructor for case when b is true
my_class(T n, int m) : n(n), conditional_members<b>{m} {};

尽管这样,您可能会因my_class专业化始终声明了两个构造函数而产生一些奇怪的副作用,即使实际上实例化一个构造函数或另一个构造函数可能无效。

这是一个SFINAE技巧,使构造函数有条件地有效地不可见,具体取决于b

#include <type_traits>

// Define conditional_members as before.

template<typename T, bool b>
class my_class : public conditional_members<b>
{
    T n;

public:
    // constructor for case when b is false
    template <typename = std::enable_if_t<!b>>
    my_class(T n) : n(n) {}

    // constructor for case when b is true
    template <typename = std::enable_if_t<b>>
    my_class(T n, int m) : conditional_members<b>{m}, n(n) {}
};

作为预览,在具有C ++ 20约束的情况下,您将可以使用这种更好,更简单的方法来编写它:

template<typename T, bool b>
class my_class : public conditional_members<b>
{
    T n;

public:
    // constructor for case when b is false
    my_class(T n) requires(!b) : n(n) {}

    // constructor for case when b is true
    my_class(T n, int m) requires(b) : conditional_members<b>{m}, n(n) {}
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM