如何基于类模板参数来专门化成员函数

时间:2010-08-21 00:08:24

标签: c++ templates member-functions explicit-specialization

问题是什么。另外,是否可以内联执行此操作?

这是一个小例子,只是为了给出一个想法......

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void do( const Foo<T> &f ) {
    z = f.z;
  }
  // specialize 'do' for Foo<int>, possible inline?

 private:
  T z;
};

3 个答案:

答案 0 :(得分:4)

你不需要做任何复杂的事情。只需使用重载和委派。请注意,我们不能只添加int重载,因为当T原来也是int时,这将是无效的重载(具有相同签名的两个函数)

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void doIt(const Foo<T> &f ) {
    doItImpl(f);
  }

 private:
  template<typename U>
  void doItImpl(const Foo<U> &f) {
    z = f.z;
  }

  void doItImpl(const Foo<int> &f) {
    /* ... */
  }

 private:
  T z;
};

或者,对于这种情况,您可以通过专业化

来完成此操作
template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void doIt(const Foo<T> &f ) {
    z = f.z;
  }

 private:
  T z;
};

template<>
inline void Foo<int>::doIt(const Foo<int> &f) {
  /* ... */
}

只有修复了所有模板参数,才能以这种方式使用专门化。换句话说,不可能部分地专门化成员函数。

答案 1 :(得分:3)

通过使成员函数成为成员函数模板并使用SFINAE(替换失败不是错误),可以获得此行为。例如:

template <typename U>
typename std::enable_if<!std::is_integral<U>::value && 
                        std::is_same<T, U>::value, void>::type
f(const Foo<U>& x)
{
}

template <typename U>
typename std::enable_if<std::is_integral<U>::value && 
                        std::is_same<T, U>::value, void>::type
f(const Foo<U>& x)
{
}

is_integral类型特征测试U是否为整数类型。如果不是,则第一个被实例化;如果是,则第二个被实例化。

is_same类型特征测试以确保TU属于同一类型。这用于确保不为Foo<T>以外的任何类型实例化成员函数模板。

此示例使用C ++ 0x <type_traits>库; Boost也有a type traits library你可以使用,它大致相同。

答案 2 :(得分:-1)

您可能会尝试做这样的事情(没有测试,可能不起作用):

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  template<typename Ty = T>
  void do( const Foo<T> &f ) {
    z = f.z;
  }

  template<>
  void do<int>( const Foo<T> &f ) {
    //specialized code
  }

 private:
  T z;
};