У меня есть шаблонный класс
template <typename Data>
class C
{
.....
}
В большинстве ситуаций я завишу от компилятора, чтобы позволить мне заменить типами Данные. Я называю нечто методов (), липкая вещь () на объектах Данных типа, поэтому что я заменяю потребностями обеспечить этому.
Я теперь должен заменить интервалом и строкой для моего Типа данных. Я не хочу специализироваться, потому что класс является уже слишком большим и потребовал бы специализации каждого метода (только с небольшим изменением кода).
Мои опции (скажите мне, если существует больше),
1) Я могу обеспечить классы обертки вокруг интервала и строки, которые реализуют нечто методов (), липкая вещь () и т.д.
2) предоставьте классу черт черты, который называет нечто () или липкая вещь () на объектах классов, которые обеспечивают нечто (), липкая вещь () (это мои существующие substitutable классы), и специализируйте эти классы для интервала и строки.
Вопросы
1) каковы относительные достоинства 1 по сравнению с 2?
2) Мои классы черт будут иметь статические методы. Класс черт может иметь нестатические методы также? Я вижу, что большинство классов черт определяет константы в STL.
3) Я делаю классы черт глобальными, или я должен передать их в как шаблонный параметр для класса C?
Вы могли бы специализировать часть класса следующим образом:
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*
.
По полдюжины каждого? Я не знаю какой-либо априорной причины использовать одно против другого в общем смысле. Ничто из того, о чем вы спрашиваете, не заставляет меня думать, что вам следует предпочесть одно другому. Единственное, о чем я могу думать, это то, что вариант 1, вероятно, потребует меньше изменений в существующих функциях. С другой стороны, клиенты не смогут просто использовать функцию для примитивов без создания оболочки.
Это действительно вопрос специфики, и вы их не предоставили.
1) каковы относительные достоинства 1 против 2?
Обертки для встроенных модулей сохраняют простоту C
. Черты сохраняют встроенные встроенные элементы. :)
Вы также можете попытаться вынести код, который отличается в зависимости от Data
, в шаблон базового класса и выделить его.
2) Мои классы свойств будут иметь статические методы. Может ли класс свойств иметь нестатические методы? Я вижу, что большинство классов свойств определяют константы в STL.
Я даже не уверен, что это все еще называется «чертой», если у него есть состояние.
FWIW, я обычно классифицирую как черты только те, которые не учитывают информацию о других типах. Что касается поведения , я бы предпочел называть это политикой. Однако я вижу, что std :: char_traits
не подходит под эти определения. : (
В любом случае, если у него есть нестатические члены, значит, у него есть состояние, и я бы больше не называл это свойство.
3) Сделать классы свойств глобальными или передать их в качестве параметра шаблона для класса C?
Передача его в качестве параметра шаблона имеет смысл только в том случае, если вы хотите, чтобы пользователи C
предоставляют свои собственные черты для всего, что они передают как Data
. Если всегда будет один шаблон признаков для int
, класс может просто его использовать. Если пользователи могут придумать свои собственные черты для int
, им понадобится способ передать их на C
.