我以为我想要模板函数专门化,但是这篇 stackoverflow 文章 https://stackoverflow.com/questions/2197141/function-template-specialization-importance-and-necessity让我觉得我真的应该通过函数重载来实现。然而,我只是不知道如何实现我想要的。
我已经能够通过类模板专业化来实现目标,但我不喜欢模板类和专业类之间有太多重复的代码。
我所拥有的是一个类,其中包含两个用于对类对象进行排序的键。此外,我想创建一个方法,match()
如果字符串的起始部分匹配(即“aaa”将匹配“aaa:zzz”,因为两个字符串的前三个字符都是“aaa”),则 for string 将返回 true,但整数、短整型等只会匹配如果完全匹配(即 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 ....
};
我不喜欢这个解决方案,因为有太多重复的代码。唯一行为不同的是 match 函数。当 key2 是 int、short 或 char 匹配时,其行为类似于 == ,而如果 key2 是 std::string 我希望它进行前缀匹配。
有没有一种“更有效”的方法来做到这一点?这可以通过 match 函数的函数重载来完成吗?如果它可以超载,我将不胜感激关于如何超载的想法。我尝试了几种重载的变体,但都惨遭失败。
提前致谢。
编辑 2010 年 10 月 12 日
我开始应用 PigBen 的答案,并能够让它解决我的问题,如上所述。然后我在实际代码上尝试了它,并意识到我过于简化了我的问题。我实际上有两个模板参数,但我正在尝试基于一个参数进行专业化。
template <int KEY1_VAL, class KEY2_TYPE> class policy_key_c
这是为了允许 typedef,例如:
typedef policy_key_c<1, int> int_policy;
typedef policy_key_c<2, std::string> str_policy;
但我发现函数专业化似乎希望指定所有模板参数。
编辑 2010 年 10 月 12 日
PigBen 的建议解决了上述问题。
后来我意识到我的问题略有不同,有两个模板参数,而我试图只专注于一个。这确实改变了问题。而且看起来我
需要做类似的事情here https://stackoverflow.com/questions/3768862/c-single-template-specialisation-with-multiple-template-parameters(这类似于詹姆斯·麦克内利斯建议的解决方案)。