C - 模板类中模板函数的单独声明/定义

新手上路,请多包涵

我知道在标头中声明模板类方法并在源文件中定义它的语法如下:

我的班级.h

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

我的类.cpp

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

但是,如果该方法也是一个模板呢?我正在向 basic_string 类添加方法,我想知道如何编写函数的实现。

我的字符串.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); ?因为现在我不仅需要指定类模板,还需要指定函数模板。我打赌我要写的代码是无效的,但它应该显示我想要完成的事情:

我的字符串.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...
}

我对模板一点也不先进。我不仅非常怀疑上述内容是否有效,而且看起来写起来很麻烦,而且可读性也不是很好。我将如何实现模板方法以及返回自己的类类型的静态模板方法?因为我不想在标题中定义它们。

原文由 Brandon Miller 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 618
2 个回答

在我回答你的问题之前,让我先说:不要这样做。通过使用自由函数来扩展 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
}

最后请注意,以下划线+大写字母开头的标识符(以及许多其他以 _ 开头的东西)是为编译器保留的,因此所有关于您的程序功能的赌注都没有。

原文由 Mark B 发布,翻译遵循 CC BY-SA 3.0 许可协议

模板外的模板成员函数定义语法如下:

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

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

所以你的代码是正确的。

需要注意的是,在 .cpp 中定义模板成员并不是很有用。在这种情况下,您应使用此模板需要使用的所有类型显式实例化它们。或者不要在这个 .cpp 之外使用它们,这没有意义。

原文由 Rost 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏