【发布时间】:2011-01-05 18:48:10
【问题描述】:
我一直在尝试调用重载的table::scan_index(std::string, ...) 成员函数,但没有成功。为了清楚起见,我已经删除了所有不相关的代码。
我有一个名为 table 的类,它有一个名为 scan_index() 的重载/模板化成员函数,以便将字符串作为特殊情况处理。
class table : boost::noncopyable
{
public:
template <typename T>
void scan_index(T val, std::function<bool (uint recno, T val)> callback) {
// code
}
void scan_index(std::string val, std::function<bool (uint recno, std::string val)> callback) {
// code
}
};
然后有一个hitlist 类,它有许多调用table::scan_index(T, ...) 的模板化成员函数
class hitlist {
public:
template <typename T>
void eq(uint fieldno, T value) {
table* index_table = db.get_index_table(fieldno);
// code
index_table->scan_index<T>(value, [&](uint recno, T n)->bool {
// code
});
}
};
最后是启动它的代码:
hitlist hl;
// code
hl.eq<std::string>(*fieldno, p1.to_string());
问题是它调用模板化版本而不是调用table::scan_index(std::string, ...)。我尝试过同时使用重载(如上所示)和专用函数模板(如下),但似乎没有任何效果。盯着这段代码几个小时后,我觉得我错过了一些明显的东西。有什么想法吗?
template <>
void scan_index<std::string>(std::string val, std::function<bool (uint recno, std::string val)> callback) {
// code
}
更新:
我从scan_index() 电话中删除了<T> 装饰。结果是带有字符串参数的调用编译得很好,但是使用其他类型(例如双精度)的调用导致以下错误:
cannot convert parameter 1 from 'double' to 'std::string'
所以我又回到了使用模板专业化。现在我得到这个错误:
error C2784: 'void table::scan_index(T,std::tr1::function<bool(uint,T)>)' :
could not deduce template argument for 'std::tr1::function<bool(uint,T)>'
from '`anonymous-namespace'::<lambda5>'
仅供参考:我使用的是 VC++ 10.0
解决方案:
我通过从table 类中删除模板化的scan_index() 函数并简单地编写四个重载函数(其中三个除了签名相同)来解决这个问题。幸运的是,它们都很短(不到十行),所以还不错。
【问题讨论】:
-
我强烈怀疑您遇到了 Koenig 名称查找问题。
-
我在这里遇到了类似的问题:stackoverflow.com/questions/3406004/…
-
不能调用非模板版本,因为你显式调用了模板
index_table->scan_index<T>...
标签: c++ templates overloading specialization