模板 class 具有用于初始化模板化基础的模板构造函数特化 class
Template class with template constructor specialization for initializing a templated base class
我有一个模板库 class,模板参数类型为 bool。这个base的构造函数参数列表class取决于模板参数是true还是false。我想从这个 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 之前,我建议将标记分派给私有委托构造函数,如 所示。
一旦您可以使用 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() {}
};
我有一个模板库 class,模板参数类型为 bool。这个base的构造函数参数列表class取决于模板参数是true还是false。我想从这个 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 之前,我建议将标记分派给私有委托构造函数,如
一旦您可以使用 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() {}
};