C ++ - separate declaration / definition of a template function in a template class

I know that the syntax for declaring a template class method in the header and its definition in the source file looks like this:

myclass.h

template <typename T> class MyClass { public: void method(T input); private: T privVar; }; 

myclass.cpp

 template <typename T> void MyClass<T>::method(T input) { privVar = input; } 

But what if the method is also a template? I am adding methods to the basic_string class, and I want to know how to write an implementation for functions.

Mystring.h

 template <class _Elem = TCHAR, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> class String : public std::basic_string<_Elem, _Traits, _Ax> { private: // Types for the conversion operators. typedef _Elem* _StrTy; typedef const _Elem* _ConstStrTy; //... public: // Conversion operators so 'String' can easily be // assigned to a C-String without calling 'c_str()'. operator _StrTy() const { return const_cast<_StrTy>(this->c_str()); } operator _ConstStrTy() const { return this->c_str(); } // ... Constructors ... /*------------ Additional Methods ------------*/ //! Converts a value of the given type to a string. template <class _ValTy> static String ConvertFrom(_ValTy val); //! Converts a string to the given type. template <class _ValTy> static _ValTy ConvertTo(const String& str); template <class _ValTy> _ValTy ConvertTo(void) const; //! Checks if a string is empty or is whitespace. static bool IsNullOrSpace(const String& str); bool IsNullOrSpace(void) const; //! Converts a string to all upper-case. static String ToUpper(String str); void ToUpper(void); // ... }; 

How could I implement template <class _ValTy> static String ConvertFrom(_ValTy val); ? Because now I not only need to specify a class template, but also a function template. I am sure that the code I'm going to write is invalid, but should show that I'm trying to execute:

Mystring.cpp

 template <class _Elem, class _Traits, class _Ax> template <class _ValTy> String<_Elem, _Traits, _Ax> String<_Elem, _Traits, _Ax>::ConvertFrom(_ValTy val) { // Convert value to String and return it... } 

I do not advance at all with templates. Not only do I very much doubt that the foregoing really seems cumbersome to write and not very readable. How can I apply template methods and static template methods that return their own class type? Because I do not want to define them in the title.

+6
source share
3 answers

Before answering your question, let me first say: do not do this. Extend std::string , using free functions instead, like a standard library that implements many algorithms. In addition, I propose to do this only for ranges, not just for string , but it is more subjective.

Also note that std::string avoids implicit conversions to C-lines, so as not to make your life harder, but to protect your code from a lot of obscure errors that might be caused by unexpected implicit conversions. I think it is very long and difficult about their implementation. Think about it: you will need a few extra points to type .c_str() once when you write the code, and for the rest of eternity, anyone who reads your code will immediately recognize that it is used as a C-style string, and not as std::string .

To answer your question, simply enter the code in the header:

 //! Converts a value of the given type to a string. template <class _ValTy> static String ConvertFrom(_ValTy val) { // Code here } 

Finally, note that identifiers starting with the underscore + capital letter (and much more, starting with _ ) are reserved for the compiler, and therefore all bets are disabled in relation to the functionality of your program.

+9
source

The syntax for defining member functions of a template outside the template is as follows:

 template <class T> struct A { template <class X> void f(); }; template<class T> template<class X> void A<T>::f() { } 

So your code is correct.

I would like to note that the definition of template members in .cpp not very useful. In this case, you must explicitly create them with all types that you must use with this template. Or do not use them outside of this .cpp , which does not make sense.

+13
source

Your function definition is valid, and it cannot be defined outside the class declaration in a less detailed way. Because you want to put a function definition in a .cpp file, you cannot use the combination of a function definition with a more concise function declaration. Having placed the function definition in the .cpp file, you will also need to explicitly specify all the necessary specializations of your template.

+2
source

All Articles