C ++ - 模板类中模板函数的单独声明/定义 [英] C++ - Separate declaration/definition for template function in template class
问题描述
我知道在一个标题中声明一个模板类方法并在源文件中定义它的语法如下:
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;
}
但是,如果方法也是一个模板?
我需要为 basic_string
类添加方法,我想知道如何编写函数的实现。
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:
//转换运算符的类型。
typedef _Elem * _StrTy;
typedef const _Elem * _ConstStrTy;
// ...
public:
//转换运算符因此'String'可以很容易地是
//分配给C-String而不调用'c_str()'。
operator _StrTy()const {
return const_cast< _StrTy>(this-> c_str
}
operator _ConstStrTy()const {
return this-> c_str();
}
// ...构造函数...
/ * ------------其他方法-------- * /
//!将给定类型的值转换为字符串。
template< class _ValTy> static String ConvertFrom(_ValTy val);
//!将字符串转换为给定类型。
template< class _ValTy> static _ValTy ConvertTo(const String& str);
template< class _ValTy> _ValTy ConvertTo(void)const;
//!检查字符串是否为空或是空格。
static bool IsNullOrSpace(const String& str);
bool IsNullOrSpace(void)const;
//!将字符串转换为全大写。
static String ToUpper(String str);
void ToUpper(void);
// ...
};
如何实现 template< class _ValTy>静态字符串ConvertFrom(_ValTy val);
?因为现在不仅需要指定类模板,而且还需要指定函数模板。我打赌我要写的代码是无效的,但它应该显示我想要完成:
MyString.cpp
template< class _Elem,class _Traits,class _Ax>
pre>
template< class _ValTy>
String< _Elem,_Traits,_Ax> String< _Elem,_Traits,_Ax> :: ConvertFrom(_ValTy val){
//将值转换为String并返回...
}
我根本没有使用模板。不仅我非常怀疑上面的是有效的,写看起来很麻烦,而且不是很可读。我将如何实现模板方法,以及返回其自己的类类型的静态模板方法?因为我不想在标题中定义它们。
解决方案在我回答你的问题之前,让我先说:Don不要这样做。通过使用自由函数代替扩展
std :: string
,很像标准库实现许多算法。此外,我建议对范围而不是string
只做这个,但是更主观。
std :: string
避免对C字符串的隐式转换不会使你的生活更难,但是为了保护你的代码免受各种各样的晦涩的错误,可能是由意想不到的转换。我会认为执行它们非常漫长。只是想想:在你编写代码时,你需要花费额外的时间来键入.c_str()
,对于其余的永久性,任何读取代码的人都会立即知道它被用作C风格的字符串,而不是作为std :: string
。
回答你的问题,只是把代码放在标题:
//!将给定类型的值转换为字符串。
template< class _ValTy> static String ConvertFrom(_ValTy val)
{
//代码在这里
}
$ b b最后注意,以下划线+大写字母开头的标识符(以及许多其他以
_
开头的)都保留给编译器,因此所有的注单都关闭了程序的功能。I am aware that the syntax for declaring a template class method in a header and defining it in a source file goes as so:
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 have am adding methods to the
basic_string
class, and I want to know how to write the implementation for the 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 not only do I need to specify the class template, but the function template too. I am betting the code I'm about to write isn't valid, but it should show what I am trying to accomplish: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 am not advanced at all with templates. Not only am I very doubtful that the above is valid, it seems cumbersome to write and not very readable. How would I go about implementing the template methods, and the static template methods which returns its own class type? Because I don't want to define them in the header.
解决方案Before I answer your question, let me first say: Don't do this. Extend
std::string
by using free-functions instead, much like the standard library implements many algorithms. Additionally I'd suggest doing it for ranges rather thanstring
s only but that's more subjective.Also note that
std::string
avoids implicit conversions to C-strings not to make your life harder, but to protect your code from a wide variety of obscure bugs that can be caused by unexpected implicit conversions. I would think very long and hard about implementing them. Just think about this: It takes you a few extra moments to type.c_str()
once when you write the code, and for the rest of eternity anyone who reads your code will immediately know that it's being used as a C-style string and not as astd::string
.To answer your question, just put 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 underscore+capital letter (and many other things starting with
_
) are reserved for the compiler and thus all bets are off as to your program's functionality.这篇关于C ++ - 模板类中模板函数的单独声明/定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!