【问题标题】:Specialization of a member of a template class for a template class parameter type模板类参数类型的模板类成员的特化
【发布时间】:2010-05-14 02:56:59
【问题描述】:

我有一个模板类 Matrix。我想为复杂类型专门化一个函数,其中 T 可以是任何东西。我试过这个:

  6 template <typename T>
  7 class Matrix {
  8       public :
  9             static void f();
 10 };          
 11 template<typename T> void Matrix<T>::f() { cout << "generic" << endl; }
 12 template<> void Matrix<double>::f() { cout << "double" << endl; }
 13 template<typename T> void Matrix<std::complex<T> >::f() { cout << "complex" << endl; }

第 13 行无法编译。我该怎么做?

【问题讨论】:

  • 我不明白这是怎么回事..
  • 他正在尝试专门化非模板成员函数。那个问题也一样。
  • 如果我的函数不是模板成员函数,第 11 行和第 12 行怎么编译得很好?
  • 模板模板参数不是这个问题的答案吗?

标签: c++ templates function member


【解决方案1】:

在第 11 行和第 12 行中,您声明了 C++ 标准 14.7/3 允许的类模板成员的显式特化(14.5.2/2 也包含一个很好的示例)。在第 13 行中,您尝试对类模板进行部分特化,但这种形式不允许这样做(这是部分特化,因为您不知道整个类型 std::complex&lt;T&gt;,因为它仍然依赖于 T)。你应该对整个班级进行部分专业化。

【讨论】:

  • 正如 Assaf Lavie 所建议的,这不能使用模板模板参数来完成,而不必部分专门化整个类吗?一堆函数将是相同的,无论是 double 或 complex 还是 float。我不想复制所有这些功能。
  • 将所有泛型函数移至基类并部分专门化继承的类可能是一个好主意。
【解决方案2】:

事实上,我通过 Boost 找到了一个聪明的方法。因为我不希望我的库依赖于 Boost,所以这里是代码:

template <class T, T val> struct integral_constant
{
      typedef integral_constant<T, val> type;
      typedef T value_type;
      static const T value = val;
};    
typedef integral_constant<bool, true>  true_type;
typedef integral_constant<bool, false> false_type;
template <typename T> struct is_complex : false_type{};
template <typename T> struct is_complex<std::complex<T> > : true_type{};

template <typename T>
class Matrix {
      public :
            static void f() { f_( typename is_complex<T>::type() ); }
      private :
            static void f_( true_type ) { cout << "generic complex" << endl; }
            static void f_( false_type ) { cout << "generic real" << endl; }
};          
template<> void Matrix<double>::f() { cout << "double" << endl; }

这样,我可以使用函数重载和模板来实现我的目标。

【讨论】:

    【解决方案3】:

    如链接答案中所述,您需要做的是专门化整个类,而不是简单的函数:

    #include <iostream>
    #include <complex>
    using namespace std;
    
    template <typename T>
    class Matrix {
    public :
        static void f();
    };
    
    template<typename T> void Matrix<T>::f() { cout << "generic" << endl; }
    template<> void Matrix<double>::f() { cout << "double" << endl; }
    
    template <typename T>
    class Matrix<std::complex<T> > {
    public:
        static void f() { cout << "complex" << endl; }
    };
    
    int main(void) {
      Matrix<complex<double> >::f();
      return 0;
    }
    

    【讨论】:

    • 我不明白。为什么我可以轻松地将其专门用于 double ,但不能用于 complex ?我想要的是完全避免专门化整个类,因为这意味着我需要复制应该重用的代码。
    • 您还可以将 f 提取到另一个类中并专门化您想要的所有内容:Matrix 可以将 f() 实现为 SpecializedF&lt;T&gt;::f(...)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多