我需要以某种方式为用户和非用户类型重载类模板。问题产生于模板类继承模板参数:
#include <iostream>
#include<string>
#include<map>
#include<type_traits>
#include<string>
using namespace std;
class Broken_imput{};//exception class
class No_such_class{};
class Io_obj; // For MAP to know about this type
//MAP: KEY - String, VALUE - function pointer
map<string,Io_obj*(*)(istream&)> func_storage;
bool read_string(istream& ss,string& str)
{
if(ss>>str)return true; // read string from the given source
return false;
}
//------------------------------------------------
//------------------------------------------------
////CLASS THAT SETS THE INTERFACE///////////////
class Io_obj
{
public:
virtual ~Io_obj(){}
virtual void print_data()= 0;
};
//-------------------------------------------------
//FUNCTION THAT READS OBJECTS LOOKS FOR THE APPROPRIATE METHOD IN MAP AND CALLS
// IT IF METHOD EXIST. METHOD READS OBJECT OF THE TYPE IT KNOWS FROM GIVEN STREAM
Io_obj* read_object(istream& stream)
{
string str;
if(!read_string(stream,str)) throw Broken_imput{};
if(auto FN=func_storage[str])return FN(stream);
throw No_such_class{};
}
////////////////SOME CLASSES//////////////////////////////////
struct Shape
{
string data;
};
struct Circle:public Shape{};
template < class T,class = enable_if_t<is_class<U>::value,U >>
class Io:public T,public Io_obj
{
public:
Io(istream& stream){ stream>>T::data;}
void print_data() override
{
cout<<T::data<<endl;
}
//read value
static Io_obj* read_value(istream& stream) { return new Io{stream};} //deligate to constructor
};
正如您所见, 类Io 继承自模板参数。对于非用户类型(例如int,float,char ...),代码不会被编译(当然它不应该是)。我需要以某种方式为非用户类型编写此模板的专门化。标签调度&amp;对象工厂帮助,但我想避免它们。谢谢。
答案 0 :(得分:2)
最简单的方法就像
template<class T, bool = std::is_class<T>::value>
class Io:public T,public Io_obj
{ /* ... */ };
template<class T>
class Io<T, false> : public Io_obj
{ /* ... */ };
如果两个专业版共享大量代码,您可能希望将其放在基类中以减少代码重复。
您也可以使用enable_if_t
(虽然不是问题中描述的方式),但它不必要地复杂化:
template<class T, class = void>
class Io:public T,public Io_obj
{ /* ... */ };
template<class T>
class Io<T, std::enable_if_t<!std::is_class<T>::value>> : public Io_obj
{ /* ... */ };
答案 1 :(得分:0)
仔细查看标准标题<type_traits>
中的设施。例如,如果std::is_class<X>::value
是非联合类类型,则true
为X
,否则为false
。这些设施可用于支持您寻求的专业化。