【问题标题】:C++ template specialization questionC++ 模板专业化问题
【发布时间】:2009-05-20 10:46:47
【问题描述】:

我正在尝试实现一个适用于所有类型的通用 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。我不知道如何设置它。有人可以建议吗?

【问题讨论】:

  • 听起来你们实现了 Java

标签: c++


【解决方案1】:

简单地为 lexical_cast 提供一个特化怎么样?

template<> string lexical_cast(Abstract* obj)
{
  return obj->toString();
}

【讨论】:

    【解决方案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()。

    【讨论】:

      【解决方案3】:

      Matthew Wilsonshims 的形式详细处理了这一问题,如this Dr Dobb's article 和书籍Imperfect C++Extended STL 中所述。它们是允许FastFormatPantheios 库一般处理参数类型的技术的基础。

      【讨论】:

        【解决方案4】:

        你只是不以 C++ 的方式思考。 C++ 已经具有“toString”,称为operator&lt;&lt;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();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-18
          • 1970-01-01
          • 2013-12-04
          相关资源
          最近更新 更多