我有两个函数,我已经为我的调试类重载了:
template<class IteratorT>
inline debug&
operator()(const std::string& name,
IteratorT begin,
IteratorT end)
{
_stream << indent(internal) << "g< " << name << " : [ ";
for (auto i = begin; i != end; i++)
_stream << (*i) << " ";
_stream << "] >" << std::endl;
return *this;
}
和
inline debug&
operator()(const std::string& name,
std::vector<uint8_t>::const_iterator begin,
std::vector<uint8_t>::const_iterator end)
{
_stream << indent(internal) << "u8< " << name << " : [ " << std::hex;
std::copy(begin, end, std::ostream_iterator<uint32_t>(_stream, " "));
_stream << "] >" << std::endl;
return *this;
}
以下是剪辑它的使用方法:
int main()
{
debug log;
std::vector<uint8_t> vec;
vec.push_back(0xde);
vec.push_back(0xad);
vec.push_back(0xc0);
vec.push_back(0xde);
log("vec", vec.begin(), vec.end());
}
输出是(因为它没有打印为十六进制字符,我省略了未格式化的结果):
g< "vec" : [ ... ] >
而不是
u8< "vec" : [ de ad c0 de ] >
由于某种原因,编译器没有选择正确的重载函数。
$ g++47 --version
g++47 (GCC) 4.7.0 20120224 (experimental)
答案 0 :(得分:2)
很遗憾,您的专业化没有被调用,因为您传递vector<uint8_t>::iterator
而不是vector<uint8_t>::const_iterator
,并且它通过模板找到完全匹配。
要修复,你要么为非const迭代器创建一个重载,要么为你的向量创建一个const-reference,并在其上调用begin()
/ end()
。
答案 1 :(得分:2)
代码中的问题是重载解析只考虑函数的参数而不考虑结果的使用方式。这意味着表达式vec.begin()
(相反vec.end()
)只考虑vec
是非常量向量,因此使用非常量版本。
虽然存在从std::vector<>::iterator
到std::vector<>::const_iterator
的隐式转换,但是这种必需的转换认为重载比解析类型为std::vector<>::iterator
的模板函数更糟糕。 / p>
截至解决方法,您可以为iterator
和const_iterator
重载(最佳解决方案,因为解决方案仅在被调用者中),或者您可以通过强制向量为const来修复调用演员的意思:static_cast<const std::vector<uint8_T>& >(vec).begin()
(这很难看,需要在所有调用中应用修复,这很难维护)
答案 2 :(得分:1)
它正在选择通用版本,因为您传递的是vector<uint8_t>::iterator
而不是vector<uint8_t>::const_iterator
。您应该添加第三个operator()
,其中包含非const
版本并将其传递给const
版本。