Как специализировать функции-члены на основе аргумента шаблона класса - PullRequest
2 голосов
/ 21 августа 2010

Что говорит вопрос. Кроме того, возможно ли сделать это встроенным?

Вот небольшой пример, чтобы дать идею ...

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 ]

4 голосов
/ 21 августа 2010

Вам не нужно делать ничего сложного. Просто используйте перегрузку и делегирование. Обратите внимание, что мы не можем просто добавить перегрузку 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) {
  /* ... */
}

Использование специализации таким способом возможно, только если все аргументы шаблона являются фиксированными. Другими словами, частичная специализация функции-члена невозможна.

3 голосов
/ 21 августа 2010

Такое поведение можно получить, сделав функцию-член шаблоном функции-члена и используя 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 для проверки того, что T и U относятся к одному типу.Это используется для гарантии того, что шаблон функции-члена не создается ни для какого типа, кроме Foo<T>.

В этом примере используется библиотека C ++ 0x <type_traits>;Boost также имеет библиотеку признаков типа , которую вы можете использовать, которая работает в основном так же.

0 голосов
/ 21 августа 2010

Вы можете попытаться сделать что-то вроде этого (не проверял, может не работать):

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;
};
...