我正在尝试实现一个适用于所有类型的通用toString()函数。我们所有的内部类都派生自Abstract,其中包含toString()的签名。换句话说,我们所有的内部类都以某种形式存在toString方法。
问题是,基本类型(int,char,double ..)没有本机toString函数。但我们确实有一个实用程序函数调用lexical_cast来返回基元的字符串值。我们不希望一大堆if语句依赖所以我正在尝试创建一个可以完成工作的模板化实用程序类。
我对此的第一次攻击如下:
template<class T>
class ObjectToString {
public:
string objectToString(T value) {
iil::stringUtils::StringSp ret(stringUtils::valueToString<T>(value));
return ret;
}
};
template<>
class ObjectToString <Abstract<T>*> {
public:
iil::stringUtils::StringSp objectToString(Abstract<T>* value) {
return iil::stringUtils::StringSp(new std::string("AAAA"));
}
};
现在的问题是,由于Abstract是一个模板化的类,它需要模板值T.我不知道如何设置它。有人可以建议吗?
答案 0 :(得分:8)
如何简单地为lexical_cast提供专业化?
template<> string lexical_cast(Abstract* obj)
{
return obj->toString();
}
答案 1 :(得分:2)
你的问题不是更简单吗?在所有Abstract对象上,您知道该怎么做,所以您只需要为内置类型提供重载函数:
string getAsString(Abstract *obj)
{
return obj->toString();
}
string getAsString(int x)
{
return intToStr(x);
}
string getAsString(double x)
{
return doubleToStr(x);
}
等,您可以根据需要实现intToStr()和doubleToStr()。
答案 2 :(得分:1)
你只是不以C ++的方式思考。 C ++已经具有“toString”,称为operator<<
到std::ostream
。你需要为你的课程实现它。
如果你想支持继承,请执行以下操作:
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <string>
class streamable {
public:
virtual void stream(std::ostream &) const = 0;
};
std::ostream &operator<<(std::ostream &out,streamable const &obj)
{
obj.stream(out);
return out;
}
// Now anything derived from streamable can be written to std::ostream
// For example:
class bar : public streamable {
int x;
int y;
public:
bar(int a,int b) : x(a),y(b){}
virtual void stream(std::ostream &out) const { out<<x<<":"<<y; }
};
int main()
{
bar b(1,3);
std::cout<< b << std::endl;
// and converted to string
std::string str=boost::lexical_cast<std::string>(b);
std::cout<< str <<std::endl;
}
C ++方式,正如您所见,您可以免费获得boost::lexical_cast
。
为您的案件编辑:
template<typename T>
class Abstract {
public:
virtual void stream(std::ostream &) const = 0;
};
template<typename T>
std::ostream &operator<<(std::ostream &out,Abstract<T> const &obj)
{
obj.stream(out);
return out;
}
现在,如果你不喜欢boost :: lexical_cast,那么实现string_cast
就像
template<typename T>
std::string string_cast(T const &obj)
{
std::ostringstram ss;
ss<<obj;
return ss.str();
}
答案 3 :(得分:1)
已经Matthew Wilson以 shims 的形式详细处理了这一问题,如this Dr Dobb's article中所述,以及书籍Imperfect C++和{{3 }}。它们是允许Extended STL和FastFormat库一般处理参数类型的技术的基础。