C++ 模板问题:选择意外函数
a C++ template question: choose the unexpect function
我正在像 std::list 那样写我的列表,所以我有这样的功能:
template <typename _Tp>
class list {
public:
// ...
iterator insert(iterator __pos, const _Tp &__val) {
// ...
}
template <typename _InputIter>
iterator insert(iterator __pos, _InputIter __begin, _InputIter __end) {
if (__begin == __end) return __pos;
// here I use the *__begin... so ...
iterator __ret = insert(__pos, *__begin);
while (++__begin != __end) insert(__pos, *__begin);
return __ret;
}
iterator insert(iterator __pos, size_t __cnt, const _Tp &__val) {
// ...
}
}
这是主要功能
int main() {
tinystd::list<int> mylist;
tinystd::list<int>::iterator it;
it = mylist.begin();
// error happens here
mylist.insert(it, 2, 20);
}
编译器似乎会选择函数 template <typename _InputIter> iterator insert(iterator __pos, _InputIter __begin, _InputIter __end)
并导致错误提示 indirection requires pointer operand ('int' invalid)
我想知道为什么会出现这种情况以及如何修改它。
非常感谢你^^
因为第二个 insert
在重载决议中获胜;给定 mylist.insert(it, 2, 20);
模板参数 _InputIter
可以推断为 int
然后它是一个完全匹配。另一方面,第三个 insert
需要从 int
到 size_t
.
的隐式转换
您可以使用 std::input_iterator
(C++20 起)指定 _InputIter
作为输入迭代器必须满足要求。
template <std::input_iterator _InputIter>
iterator insert(iterator __pos, _InputIter __begin, _InputIter __end) {
// ...
}
在 C++20 之前,您可以对 _InputIter
施加限制,例如必须与 operator*
.
一起使用
template <typename _InputIter, std::void_t<decltype(*std::declval<_InputIter>())>* = nullptr>
iterator insert(iterator __pos, _InputIter __begin, _InputIter __end) {
// ...
}
我正在像 std::list 那样写我的列表,所以我有这样的功能:
template <typename _Tp>
class list {
public:
// ...
iterator insert(iterator __pos, const _Tp &__val) {
// ...
}
template <typename _InputIter>
iterator insert(iterator __pos, _InputIter __begin, _InputIter __end) {
if (__begin == __end) return __pos;
// here I use the *__begin... so ...
iterator __ret = insert(__pos, *__begin);
while (++__begin != __end) insert(__pos, *__begin);
return __ret;
}
iterator insert(iterator __pos, size_t __cnt, const _Tp &__val) {
// ...
}
}
这是主要功能
int main() {
tinystd::list<int> mylist;
tinystd::list<int>::iterator it;
it = mylist.begin();
// error happens here
mylist.insert(it, 2, 20);
}
编译器似乎会选择函数 template <typename _InputIter> iterator insert(iterator __pos, _InputIter __begin, _InputIter __end)
并导致错误提示 indirection requires pointer operand ('int' invalid)
我想知道为什么会出现这种情况以及如何修改它。 非常感谢你^^
因为第二个 insert
在重载决议中获胜;给定 mylist.insert(it, 2, 20);
模板参数 _InputIter
可以推断为 int
然后它是一个完全匹配。另一方面,第三个 insert
需要从 int
到 size_t
.
您可以使用 std::input_iterator
(C++20 起)指定 _InputIter
作为输入迭代器必须满足要求。
template <std::input_iterator _InputIter>
iterator insert(iterator __pos, _InputIter __begin, _InputIter __end) {
// ...
}
在 C++20 之前,您可以对 _InputIter
施加限制,例如必须与 operator*
.
template <typename _InputIter, std::void_t<decltype(*std::declval<_InputIter>())>* = nullptr>
iterator insert(iterator __pos, _InputIter __begin, _InputIter __end) {
// ...
}