簡體   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