我知道在标头中声明模板类方法并在源文件中定义它的语法如下:
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:
// 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);
// ...
};
我如何实施template <class _ValTy> static String ConvertFrom(_ValTy val);
?因为现在我不仅需要指定类模板,还需要指定函数模板。我打赌我要编写的代码无效,但它应该显示我想要实现的目标:
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...
}
我对模板一点也不高级。我不仅非常怀疑上述内容是否有效,编写起来似乎很麻烦而且不太可读。我将如何实现模板方法,以及返回其自己的类类型的静态模板方法?因为我不想在标题中定义它们。
答案 0 :(得分:14)
模板外部模板成员函数定义的语法如下:
template <class T> struct A
{
template <class X> void f();
};
template<class T> template<class X> void A<T>::f()
{
}
所以你的代码是正确的。
请注意,在.cpp
中定义模板成员并不是很有用。在这种情况下,您应使用此模板使用所有类型显式实例化它们。或者不要在.cpp
之外使用它们,这是没有意义的。
答案 1 :(得分:10)
在我回答你的问题之前,我先说:不要这样做。通过使用自由函数来扩展std::string
,就像标准库实现许多算法一样。另外,我建议仅针对范围而不是string
进行,但这更主观。
另请注意,std::string
避免了对C字符串的隐式转换,不会让您的生活更加艰难,而是为了保护您的代码免受可能由意外的隐式转换引起的各种模糊错误的影响。我认为实施它们需要很长时间。试想一下:在编写代码时,需要花费一些额外的时间来输入.c_str()
一次,在剩余的时间里,任何读取代码的人都会立即知道它被用作C风格的字符串而不是std::string
。
要回答您的问题,只需将代码放在标题中:
//! Converts a value of the given type to a string.
template <class _ValTy> static String ConvertFrom(_ValTy val)
{
// Code here
}
最后请注意,以下划线+大写字母开头的标识符(以及以_
开头的许多其他内容)都是为编译器保留的,因此所有的投注都是关于程序功能的。
答案 2 :(得分:2)
您的函数定义有效,并且不能以较不详细的方式在类声明之外定义。由于您希望将函数定义放在.cpp文件中,因此无法将函数定义与更简洁的函数声明相结合。通过将函数定义放在.cpp文件中,您还必须显式实例化模板类所需的所有特化。