【问题标题】:C++: How to partial specialization a template function in a template classC++:如何部分特化模板类中的模板函数
【发布时间】:2013-11-22 14:55:24
【问题描述】:

代码会说话:

template<typename Group>
struct Vector3D {
    Group x, y, z;
    Vector3D(Group x, Group y, Group z) : x(x), y(y), z(z) {
    }
    template<int p> Group Norm() const;
};

template<typename Group> template<int p> 
Group Vector3D<Group>::Norm() const {
    return pow( pow(x, p) + pow(y, p) + pow(z, p), (1.0 / p) );
}

/*
template<typename Group> template<>
Group Vector3D<Group>::Norm<2>() const {
    return sqrt( x * x + y * y + z * z );
}*/

注释块在vc11(vs2012)中编译失败

谁能帮忙指出部分特化 Norm 函数的正确方法是什么?

【问题讨论】:

    标签: c++ templates template-specialization specialization


    【解决方案1】:

    如果不专门化类本身,就无法专门化成员模板。为此,您将需要使用不同的机制。例如,您可以使用int2type 模板将模板参数映射到可以作为参数传递给一组重载模板的类型。考虑一下如何完成这个过于简化的草图:

    template <int N> struct int2type {};
    
    template <int N> void normImpl(int2type<N>*) {
    ...
    }
    void normImpl(int2type<2>*) {
    ...
    }
    template <int N> void norm() {
       return normImpl(static_cast<int2type<N>*>(0));
    }
    

    这可以在你的类内部实现(除了int2type 是一个很好的外部实用程序)。

    【讨论】:

      【解决方案2】:

      就像在某些类型的场景中一样,另一个级别的间接性可以帮助...

      #include <iostream>
      #include <cmath>
      using namespace std;
      
      template <typename Group, int p>
      struct ApplyNorm
      {
          static Group apply(Group x, Group y, Group z)
          { return pow( pow(x, p) + pow(y, p) + pow(z, p), (1.0 / p) ); }
      };
      
      // Here specialize for 2
      template <typename Group>
      struct ApplyNorm<Group, 2>
      {
          static Group apply(Group x, Group y, Group z)
          { 
              std::cout << "spec: " << std::endl;
              return sqrt( x * x + y * y + z * z ); 
          }
      };
      
      
      template<typename Group>
      struct Vector3D {
          Group x, y, z;
          Vector3D(Group x, Group y, Group z) : x(x), y(y), z(z) {
          }
          template<int p> Group Norm() const;
      };
      
      template<typename Group> template<int p> 
      Group Vector3D<Group>::Norm() const {
          return ApplyNorm<Group, p>::apply(x, y, z); // use the helper...
      }
      
      int main() {
          // your code goes here
          Vector3D<double> v(1., 2., 3.);
          std::cout << v.Norm<1>() << std::endl;
          std::cout << v.Norm<2>() << std::endl;
          return 0;
      }
      

      【讨论】:

      • +1 在我的回答中没有提到,但是在不同的选择中,转发到可以部分特化的类模板的静态成员是另一个不错的选择
      猜你喜欢
      • 1970-01-01
      • 2011-12-25
      • 2011-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      相关资源
      最近更新 更多