【问题标题】:how to specialize templated member functions of non-templated classes?如何专门化非模板类的模板成员函数?
【发布时间】:2010-07-16 16:16:01
【问题描述】:

假设我有一个文件 alpha.h:

class Alpha {
public:
    template<typename T> void foo();
};

template<> void Alpha::foo<int>() {}
template<> void Alpha::foo<float>() {}

如果我在多个 cpp 文件中包含 alpha.h 并使用 GCC 4.4 编译,它会抱怨在多个目标文件中有多个 foo&lt;int&gt;foo&lt;float&gt; 定义。对我来说很有意义,所以我将最后两行更改为:

template<> extern void Alpha::foo<int>() {}
template<> extern void Alpha::foo<float>() {}

但是 GCC 说:

显式模板特化 不能有存储类

好的...那么我应该如何正确执行此操作?我担心 C++ 不允许我首先尝试做的事情,在这种情况下是否有一个好的习语可以完成同样的事情?

【问题讨论】:

    标签: c++ templates template-specialization


    【解决方案1】:

    使用内联关键字

    template<> inline void Alpha::foo<int>() {}
    

    或者,在单独的 cpp 文件中提供实现

    【讨论】:

      【解决方案2】:

      您可以转发声明以及内联选项:

      // .h
      template<> void Alpha::foo<int>();
      
      //.cpp
      template<> void Alpha::foo<int>() {}
      

      【讨论】:

        【解决方案3】:

        从 ODR 的角度来看,完全(明确)专门化的模板不再是模板,因此它与同类的非模板实体遵循相同的 ODR 原则。 (我相信这条规则有一些例外,但对于我们的目的来说已经足够了)。

        在您的情况下,出于 ODR 目的,完全专用的函数模板是一个普通函数。所以,作为一个普通函数,它应该在头文件中声明,在一个且只有一个实现文件中定义

        【讨论】:

          【解决方案4】:

          不需要单独的声明或内联键。 PF 下面的工作代码。

          #include<iostream>
          
          class temp
          {
          public:
              template <class T>
              T add1(T a, T b)
              {
                      return (a + b);
              }
          };
          
          template<>
          std::string temp::add1<std::string>(std::string aa, std::string bb)
          {
              return aa+bb;
          }
          
          int main()
          {
              temp *tc = new temp();
              std::cout << tc->add1<float>(5.7, 4.5) << std::endl;
              std::cout << tc->add1<std::string>("my ","program") << std::endl;
          }
          

          输出是:

          10.2

          我的程序

          【讨论】:

          • 当然,如果您将所有内容都放在一个文件中......但这不是 OP 的问题,他有多个对象文件的问题。 IE。他想知道当头文件在多个编译单元中使用时如何使它工作。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-02-20
          • 2016-05-03
          • 1970-01-01
          • 1970-01-01
          • 2021-06-21
          • 1970-01-01
          • 2016-07-02
          相关资源
          最近更新 更多