c++ - 具有模板构造函数特化的模板类,用于初始化模板化基类
问题描述
我有一个模板基类,其模板参数为 bool 类型。这个基类的构造函数参数列表取决于模板参数是真还是假。我想从这个类派生另一个模板类,其模板参数是任何类型。我需要这个派生类根据该类型的特征调用该基类的正确构造函数。
下面的例子并不是包罗万象的。无论是否完整,基类模板 bool 都可以用于任何类型特征。此外,传递给派生类的模板参数的类型可以是任何类型。
我已经尝试了几种不同的方法来尝试语法化这个东西,但我得到的最接近的是下面的代码。然而,由于派生类需要完全专业化,它会出错。
#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 类型的通用性,并且不能完全专门化 CL 类。什么是正确的语法?有解决方法吗?
我正在使用 gcc-g++ 版本 8.3.0-6。
提前致谢!
解决方案
您的派生类应该是:
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;
使您从基类继承构造函数(自 c++11 起可用)。
在您的示例中,您还应该更改:
CL<int> c; // integral
进入,例如:
CL<int> c(10); // integral
推荐阅读
- c# - Xamarin android C# grpc 客户端无法创建频道
- python - Tensorflow 深度学习模型对 10 个类的准确率较低,而在 3 个类的集合中表现非常好
- sql-server - 插入适用于不同的查询,但不适用于 3 列
- javascript - 未捕获的类型错误:无法访问属性“长度”,e 未定义
- docker - 将流写入 Parquet 文件,仅创建 _spark_metadata 文件夹但不创建 parquet 文件
- c# - 以管理员身份从 Outlook 发送邮件时 .ost 文件出现问题
- c - 大内存区域的“clflush”不刷新?
- javascript - 出了点问题!元素类型无效:应为字符串(用于内置组件)或用于 HOC 的类/函数
- sql - 在两个不同的列之间创建时间戳范围
- mysql - 如何从 MySql 中的表中删除重复条目