Вопрос о чертах C ++ - PullRequest
       5

Вопрос о чертах C ++

8 голосов
/ 11 июня 2010

У меня есть шаблонный класс

template <typename Data>
class C
{
.....
}

В большинстве случаев я полагаюсь на компилятор, который позволяет мне подставлять типы для данных.Я вызываю методы foo (), goo () для объектов типа Data, поэтому то, что я подставляю, должно это обеспечить.

Теперь мне нужно заменить int и string для моего типа данных.Я не хочу специализироваться, потому что класс уже слишком большой и потребует специализации каждого метода (только с небольшим изменением кода).

Мои параметры (скажите, пожалуйста, если их больше)

1) Я могу предоставить классы-обертки для int и string, которые реализуют методы foo (), goo () и т. Д.

2) предоставляют свойства класса traits, которые вызывают foo () или goo () для объектов классов, которые предоставляют foo (), goo () (это мои настоящие замещаемые классы) и специализируют эти классы для int и string.

Вопросы

1) Каковы относительные достоинства 1 против 2?

2) Мои классы черт будут иметь статические методы.Может ли класс признаков иметь нестатические методы?Я вижу, что большинство классов признаков определяют константы в STL.

3) Я делаю классы признаков глобальными или я должен передать их в качестве параметра шаблона для класса C?

Ответы [ 3 ]

7 голосов
/ 11 июня 2010

Вы можете специализировать часть класса следующим образом:

template <typename Data>
class C
{
  void foo();

  // lot of other stuff
};

// specialize part of class C 
// (some members of a class C will have specific 
//  implementation for specific types)
template<> void C<int>::foo() { std::cout << "int" << std::endl; }
template<> void C<std::string>::foo() { std::cout << "string" << std::endl; }
// same for goo

Синтаксис, приведенный выше, разрешен стандартами C ++ 14.7 / 3 и 14.5.2 / 2. Нет необходимости переписывать все вещи из класса C несколько раз.

Обратите внимание, что таким способом нельзя частично специализировать шаблонный класс. Например, вы не можете таким образом определять различные функции для типов Data и Data*.

2 голосов
/ 11 июня 2010

1) Каковы относительные достоинства 1 против 2?

Обертки вокруг встроенных модулей упрощают C. Черты сохраняют встроенные встроенные модули. :)
Вы также можете попытаться выделить код, который отличается в зависимости от Data, в шаблон базового класса и специализировать его.

2) Мои классы черт будут иметь статические методы. Может ли класс признаков иметь нестатические методы? Я вижу, что большинство классов черт определяют константы в STL.

Я даже не уверен, что он все еще называется "чертами", если у него есть состояние.
Кстати, я обычно классифицирую как признаки только те, которые выделяют информацию о других типах. Когда дело доходит до поведения , я бы скорее назвал это политикой. Однако я вижу, что std::char_traits не соответствует этим определениям. :( В любом случае, если у него есть нестатические члены, то у него есть состояние, и я больше не буду называть это чертами.

3) Сделать ли классы признаков глобальными или передать их в качестве параметра шаблона для класса C?

Передача его в качестве параметра шаблона имеет смысл только в том случае, если вы хотите, чтобы пользователи C предоставили свои собственные черты для всего, что они передают как Data. Если для int всегда будет один шаблон черт, класс может просто использовать это. Если пользователи могут придумать свои собственные черты для int, им нужен способ передать его в C.

0 голосов
/ 11 июня 2010

Полдюжины каждого? Я не знаю ни одной априорной причины использовать одно против другого в общем смысле. Ничто из того, о чем ты спрашиваешь, не заставляет меня думать, что тебе следует выбирать одно над другим. Единственное, о чем я могу думать, это то, что для выбора 1, вероятно, потребуется меньше изменений существующих функций. С другой стороны, клиенты не смогут просто использовать функцию на примитивах без создания оболочки.

Это действительно вопрос специфики, а вы их не предоставили.

...