【问题标题】:a C++ template question: choose the unexpect function一个 C++ 模板问题:选择意外函数
【发布时间】:2022-01-18 08:34:04
【问题描述】:

我正在像 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 &lt;typename _InputIter&gt; iterator insert(iterator __pos, _InputIter __begin, _InputIter __end) 并导致错误提示indirection requires pointer operand ('int' invalid)

我想知道为什么会发生这种情况以及如何修改它。 非常感谢你^^

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    因为第二个insert 在重载决议中获胜;给定mylist.insert(it, 2, 20);,模板参数_InputIter 可以推导出为int,然后它是完全匹配的。另一方面,第三个insert 需要从intsize_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) {
        // ...
    }
    

    【讨论】:

    • 非常感谢!效果很好。
    • "eg must be used with operator*" 这个约束似乎太松了(std::optional也有operator*),不应该是is_convertible_v&lt;typename std::iterator_traits&lt;_InputIter&gt;::iterator_category, std::input_iterator_tag&gt;吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    相关资源
    最近更新 更多