#pragma once ///////////////////////////////////////////////////////////////////// // TemplatesIntro.h - Demonstrate Template Syntax // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2017 // ///////////////////////////////////////////////////////////////////// /* * - Template classes use one or more unspecified types, defined by * arguments in the template declaration: template. * * - Because the arguments are not specified, the C++ compiler cannot * generate object code until it sees an application instantiate * the template type(s). * * - The consequence of this is that all template definitions must be * placed in a header file, to be included by the application. * * - Unlike C# and Java, template syntax checking happens when the * application is compiled. * * - That means that a template class can use any methods for the * unspecified type and will successfully compile. If the type does * not have a method used by the template code, a compile time error * occurs when the application is compiled. */ #include #include ///////////////////////////////////////////////////////////////////// // Convert class // - (de)serializes objects of type T (from)to strings // - generates a type identifier using Run-Time Type Identification // template class Convert { public: virtual ~Convert() {} static std::string toString(const T& t); static T fromString(const std::string& str); static std::string id(const T& t); }; /*----< serialize t to a std::string >-----------------------------*/ /* * Assumes that T defines an insertion operator. */ template std::string Convert::toString(const T& t) { std::ostringstream out; out << *const_cast(&t); return out.str(); } /*----< create an instance of T from a std::string >---------------*/ /* * Assumes that T defines an extraction operator. * To succeed str must be created from Convert::toString(const T& t). */ template T Convert::fromString(const std::string& str) { std::istringstream in(str); T value; in >> value; // istringstream extraction provides the conversion return value; } /*----< create an id string from an instance of T using RTTI >----*/ template std::string Convert::id(const T& t) { return typeid(t).name(); } ///////////////////////////////////////////////////////////////////// // TemplateDemo // - demonstrates template syntax // template class TemplateDemo { public: TemplateDemo() : state(T()) {} TemplateDemo(const T& t) : state(t) {} ~TemplateDemo() {} T& value(); private: T state; }; /*----< return reference to internal state >-----------------------*/ template T& TemplateDemo::value() { return state; } /*----< insertion operator >---------------------------------------*/ template std::ostream& operator<<(std::ostream& out, TemplateDemo& td) { out << td.value(); return out; } /*----< extraction operator >--------------------------------------*/ template std::istream& operator>>(std::istream& in, TemplateDemo& td) { in >> td.value(); return in; }