我有一个模板类,否则可以正常工作,除非我需要在类型T为字符串的情况下重载insert方法。
template <class T>
class hashtable{
public:
void insert(T item){
/* Do Stuff */
};
template<> void insert(string item){
/* Do different stuff */
};
}
这是抛出错误C2912:显式特化; 'void hashtable :: insert(std :: string)'不是函数模板的特化。
我不确定我做错了什么,或者我怎么解决这个问题。根据T是否为字符串,我需要的是一种不同地调用insert函数的方法。
答案 0 :(得分:2)
您根本不需要添加template
字。你只需重载模板功能。
class hashtable{
public:
template <typename T>
void insert(T item){
/* Do Stuff */
};
void insert(string item){
/* Do different stuff.
Implementation can go to *.cpp file if necessary.
*/
};
};
请注意,无论设计如何,当您尝试insert
可隐式转换为std :: string的类型(包括const std::string &
和const char*
)时,您都会遇到麻烦。信不信由你,在C ++ 03中,std :: string甚至有来自int
的隐式构造函数!
这就是为什么人们通常更喜欢将散列表类化身,而不是函数。
答案 1 :(得分:0)
您需要在模板括号中指定专门化:
template<class string> void insert(string item) ...
模板&lt;&gt;消除类专门化中的所有参数时使用。这里有一个例子:
http://www.cplusplus.com/doc/tutorial/templates/#template_specialization
答案 2 :(得分:0)
在类定义之外编写专门化:
template <typename T> class hashtable { /* ... */ };
template <> void hashtable<std::string>::insert(std::string item)
{
// ...
}
答案 3 :(得分:0)
我不确定这堂课的重点。你在T类中有一个内部对象吗?如果没有,我会做以下事情:
class hashtable{
public:
template <typename T>
void insert(T item){
/* Do Stuff */
};
template<>
void insert(string item){
/* Do different stuff */
};
}
如果你在课堂上确实有T型,那么也许你正在寻找这个:
template <typename T>
class hashtable{
public:
template <typename P>
void insert(P item){
/* Do Stuff */
};
template<>
void insert(string item){
/* Do different stuff */
};
}
你需要详细说明你想要做的事情。
答案 4 :(得分:0)
最简单的方法是标记dispstching /
创建一个继承自std::true_type
或std::false_type
的traits类,具体取决于您要使用的实现。
然后使用impl
和ture_type
参数编写两个false_type
方法,如下所示:
template<typename T> void insert(T&& t) { insert_impl(std::forward<T>(t), traits_test<T>() ); }
template<typename T> void insert_impl(T t, std::true_type descriptive_name ){ code }
template<typename T> void insert_impl(T t, std::false_type another_desc_name ){ code }
通过这样做,你可以避免不必要的专业化样板,只需调整traits类就可以轻松扩展代码。
方法专业化有点古怪,甚至比功能模板专业化更多。通过使用标签调度,根据我的经验,对发生的事情的推理变得更容易。
答案 5 :(得分:0)
好吧,也许最好以另一种方式思考 - 你有模板数据结构,所以你应该专注于整个结构而不仅仅是一个函数 - 因为如果你需要专门化这种类型的另一种方法(这里 - 对于字符串),你会把它专门化在同一个类中 - 它会破坏代码。我的解决方案的变体如上:
template <class T>
class hashtable{
public:
void insert(T item){
/* Do Stuff */
};
}
template <string>
class hashtable{
public:
void insert(string item){
/* Do different stuff */
};
}
作为版本 - 您可以使用模板散列函数编写散列表 - 这将删除任何特化。但显然,你需要为字符串编写自己的函数。 int和hashtable的示例:
template <class T>
LinearHashFunction {
int a,b;
static const int prime = /* some big prime number */
LinearHashFunction(int a, int b):a(a), b(b) {}
int operator()(T item) {
return static_cast<int>(item)*a + b;
}
};
template <class T, class THashFunction>
class hashtable{
private:
THashFunction<T> hash;
public:
void insert(T item){
/* Do Stuff */
// get hash:
int elementsHash = hash(item);
};
template<> void insert(string item){
/* Do different stuff */
};
};