Я думал, что хочу специализовать функции шаблонов, но эта статья о стековом потоке заставляет меня думать, что я действительно должен делать перегрузку функций. Однако я просто не вижу, как я могу достичь того, чего хочу.
Мне удалось достичь цели с помощью специализации шаблонов классов, но мне не нравится тот факт, что у меня так много копируется кода между классом шаблонов и специализированным классом.
У меня есть класс с двумя ключами, которые используются для сортировки объектов класса. Более того, я хочу создать метод match()
, который для строки вернет true, если начальная часть строки совпадает (то есть «aaa» будет соответствовать «aaa: zzz», потому что первые три символа обеих строк - «aaa») ), но целые, шорты и т. д. будут совпадать только в случае их точного соответствия (т. е. 1 == 1).
Я получил это для работы, используя специализацию класса, как показано ниже:
template <class KEY2_TYPE>
class policy_key_c
{
public:
policy_key_c (int _key1,
KEY2_TYPE _key2) :
key1(_key1),
key2(_key2)
{};
virtual ~policy_key_c(void) {};
virtual std::string strIdx (void) const {
// combine key1 and key2 into an index to be returned.
}
//
// operator <
//
virtual bool operator< (const policy_key_c &b) const {
return (operator<(&b));
}
virtual bool operator< (const policy_key_c *p) const {
// if the primary key is less then it's less, don't check 2ndary
if (key1 < p->key1) {
return (true);
}
// if not less then it's >=, check if equal, if it's not equal then it
// must be greater
if (!(key1 == p->key1)) {
return (false);
}
// its equal to, so check the secondary key
return (key2 < p->key2);
}
//
// operator ==
//
virtual bool operator== (const policy_key_c &b) const {
return(operator==(&b));
}
virtual bool operator== (const policy_key_c *p) const {
// if the primary key isn't equal, then we're not equal
if ((key1 != p->key1)) {
return (false);
}
// primary key is equal, so now check the secondary key.
return (key2 == p->key2);
}
//
// match
//
virtual bool match (const policy_key_c &b) const {
return(operator==(&b));
}
virtual bool match (const policy_key_c *p) const {
return (operator==(p));
}
protected:
int key1; // The primary key
KEY2_TYPE key2; // The secondary key.
// ... other class data members ....
};
// Now specialize the template for a string as the secondary key
//
template <>
class policy_key_c<std::string>
{
public:
//
// .... all the other functions
//
//
// match
//
virtual bool match (const policy_key_c &b) const {
return(operator==(&b));
}
virtual bool match (const policy_key_c *p) const {
// do a prefix string match rather than a complete match.
return (key2.substr(0, p->key2.lenght()) == p->key2);
}
protected:
int key1; // The primary key
std::string key2; // The secondary key.
// ... other class data members ....
};
Мне не нравится это решение, потому что там так много копируемого кода. Единственное, что ведет себя по-другому - это функция соответствия. Когда key2 представляет собой int, short или char соответствует, ведет себя как == wherease, если key2 является std :: string, я хочу, чтобы оно соответствовало префиксу.
Есть ли "более эффективный" способ сделать это? Может ли это быть сделано с перегрузкой функции соответствия? Если это может быть перегружено, я был бы признателен за идеи о том, как. Я пробовал несколько вариантов перегрузки и с треском провалился.
Заранее спасибо.
Изменить 10/12/10
Я начал применять ответ PigBen и смог заставить его работать с моей проблемой, как указано выше. Затем я попробовал это на своем реальном коде и понял, что упрощаю свою проблему. На самом деле у меня есть два параметра шаблона, но я пытаюсь специализироваться на основе одного.
template <int KEY1_VAL, class KEY2_TYPE> class policy_key_c
Это должно было разрешить typedefs, такие как:
typedef policy_key_c<1, int> int_policy;
typedef policy_key_c<2, std::string> str_policy;
Но я обнаружил, что специализация функции, по-видимому, требует указания всех параметров шаблона.
Изменить 10/12/10
Предложение PigBen решило проблему, как указано.
Позже я понял, что моя проблема немного отличается, с двумя параметрами шаблона, и я пытался специализироваться только на одном. Это действительно меняет вопрос. И, похоже, я
нужно сделать что-то вроде готового здесь (что аналогично предлагаемому решению Джеймса МакНеллиса).