簡體   English   中英

模板 class 模板構造函數專門用於初始化模板化基礎 class

[英]Template class with template constructor specialization for initializing a templated base class

我有一個模板庫 class,模板參數為 bool 類型。 這個基礎 class 的構造函數參數列表取決於模板參數是真還是假。 我想從這個 class 派生另一個模板 class,模板參數可以是任何類型。 我需要這個派生的 class 來調用該 Base class 的正確構造函數,具體取決於該類型的特征。

下面的例子並不是包羅萬象的。 整體與否,基本 class 模板 bool 可以用於任何類型的特征。 此外,傳遞給派生 class 的模板參數的類型可以是任何類型。

我已經嘗試了幾種不同的方法來嘗試語法化這個東西,但我得到的最接近的是下面的代碼。 但是,由於派生的 class 需要完全專業化,因此它會出錯。

#include <type_traits>
using namespace std;

template<bool IsIntegral> struct Base 
{
    template<bool IsI = IsIntegral,
        typename I = typename enable_if<IsI>::type>
    Base(int param) {}

    template<bool IsI = IsIntegral,
        typename I = typename enable_if<!IsI>::type>
    Base() {}
};

template<class T> class CL :
    Base<is_integral<T>::value>
{
public:
template<bool U = is_integral<T>::value> CL();

};

template<>
template<class T>
CL<T>::CL<true>() : // error: ISO C++ forbids declaration of ‘CL’ with no type [-fpermissive]
                    // CL<T>::CL<true>() :
                    //                 ^
                    // error: non-type partial specialization ‘CL<true>’ is not allowed
                    // error: no declaration matches ‘int CL<T>::CL()’
                    // CL<T>::CL<true>() :
                    // ^~~~~
    Base(4) { }

template<>
template<class T>
CL<T>::CL<false>()  // error: ISO C++ forbids declaration of ‘CL’ with no type [-fpermissive]
                    // CL<T>::CL<true>() :
                    //                 ^
                    // error: non-type partial specialization ‘CL<true>’ is not allowed
                    // error: no declaration matches ‘int CL<T>::CL()’
                    // CL<T>::CL<true>() :
                    // ^~~~~
    { }

int main () {
    // Base<true> a; // won't compile as expected
    Base<true> a(4);
    // Base<false> b(4); // won't compile as expected
    Base<false> b;
    
    CL<int> c; // integral
    CL<int*> d; // non-integral
    // should work for any types other than int and int*

    return 0;
}

我需要保持 T 型通用,不能完全專門化 class CL。 什么是正確的語法? 有解決方法嗎?

我正在使用 gcc-g++ 版本 8.3.0-6。

提前致謝!

在玩了這個之后,我想出了這個,我猜它屬於“解決方法”的范疇,你願意考慮:

template<class T> class CL :
    Base<is_integral<T>::value>
{
public:
    CL() : CL{ is_integral<T>{} } {}

    template<typename U=T>
    CL(std::true_type) : Base<true>{4} {}

    template<typename U=T>
    CL(std::false_type)
    {
    }
};

您派生的 class 應該是:

template<class T> class CL :
Base<is_integral<T>::value>{
  public:
     using base_t = Base<is_integral<T>::value>;
     using base_t::base_t;
};

using base_t::base_t; 使您從基礎 class 繼承構造函數(自 c++11 起可用)。

在您的示例中,您還應該更改:

CL<int> c; // integral

進入,例如:

CL<int> c(10); // integral

C++20 和 requires 子句

在 C++20 之前,我建議將標簽分派給私有委托構造函數,如@SamVarshavchik 的回答中所示。

一旦您可以使用 C++20,您就可以使用requires 子句輕松構建這些關系:

#include <type_traits>

template <bool IsIntegral>
struct Base  {
    Base(int param) requires IsIntegral {}
    Base() requires (!IsIntegral) {}
};

template<typename T> 
class CL : Base<std::is_integral<T>::value> {
    static constexpr bool kIsIntegral = std::is_integral_v<T>;
 public:
    CL() requires kIsIntegral : CL::Base(4) {}
    CL() requires (!kIsIntegral) : CL::Base() {}    
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM