繁体   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