c++ - 为迭代器和无符号整数重载 + 运算符
问题描述
我正在尝试+
为列表迭代器和无符号整数重载运算符(用于练习)。下面的代码似乎工作正常。解释它应该做什么:如果iter
是一个迭代器和k
一个无符号整数,那么iter+k
(或operator+(iter, k)
)返回一个从递增iter
k 次获得的迭代器。
list<int>::iterator operator+(list<int>::iterator iter, unsigned k)
{
while (k != 0)
{
++iter;
--k;
}
return iter;
}
但是,当我这样模板化时:
template<typename T>
typename list<T>::iterator
operator+(typename list<T>::iterator iter, unsigned k)
{
while (k != 0)
{
++iter;
--k;
}
return iter;
}
并运行一些简单的东西
int main(){
list<int> l{1,2};
list<int>::iterator q = l.begin();
q+1;
}
我收到一个我无法破译的大错误。我也试过无济于事:
int main(){
list<int> l{1,2};
list<int>::iterator q = l.begin();
operator+<int>(q,1);
}
关于为什么会发生这种情况以及如何解决它的任何想法将不胜感激!
解决方案
问题是模板类型参数T
在非推导上下文中,无法推导。为了使其可推断,您可以这样做:
template<typename T>
T operator+(T iter, unsigned k)
{ ... }
请注意,这种重载可能会造成很多伤害,因为T
不限于std::list<T>::iterator
. SFINAE 可以帮助:
template<typename T, typename = std::enable_if_t<
std::is_same_v<T, typename std::list<
typename std::iterator_traits<T>::value_type>::iterator>>>
T operator+(T iter, unsigned k)
{ ... }
添加。
为什么operator+<int>(q, 1);
失败的问题更加微妙。首先,引用标准,[temp.arg.explicit]/8 (另见那里的一个例子):
但是,当使用带有显式模板参数的函数模板时,调用没有正确的语法形式,除非在调用点有一个具有该名称的函数模板可见。如果没有这样的名称可见,则该调用在语法上不是格式正确的,并且不适用依赖于参数的查找。如果某些此类名称可见,则应用依赖于参数的查找,并且可以在其他名称空间中找到其他函数模板。
我们这里有这样一个函数模板,就是我们的operator+
. 因此,ADL 尝试operator+<int>
在std::
. 但是,当某些operator+
模板使用<int>
. 哪一个以及它如何失败,取决于特定的标准库实现。
例如,gcc 8.1 尝试实例化
template<class _Iterator> constexpr
std::move_iterator<_IteratorL> std::operator+(
typename std::move_iterator<_IteratorL>::difference_type,
const std::move_iterator<_IteratorL>&)
[with _Iterator = int]
并在内部某处失败
error: no type named 'reference' in 'struct std::iterator_traits<int>'
...
如果我们禁用 ADL,它将按预期工作:
::operator+<int>(q, 1);
或者
(operator+<int>)(q, 1);
推荐阅读
- python - 为什么我收到错误:OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:376: 错误:
- android - 无法在 android studio 3.6 中进行 git push 或 pull
- node.js - SyntaxError:意外的令牌'<' SystemJs(0.21.5v)
- javascript - process.env.UV_THREADPOOL_SIZE 在 macos 上总是显示 undefined
- java - 如何在 Spring 应用程序中为 Java Melody Monitor URL 添加安全性
- ssrs-2008 - SSRS 报告需要根据数据集行显示 n 次
- c# - 在 UWP 中应用 TranslateTransform 时,外部渲染的折线段不显示
- python - 在python中将字符串(带时区)转换为日期时间
- angular - AWS - 使用 API Gateway 从后端下载文件时缺少 CSV 文件名
- php - 以custom-post-type提交表单后下载pdf文件