当将 std::vector::begin() 传递给 std::vector::insert 时,编译器如何推断出要调用哪个版本的 std::vector::begin() ?

ula*_*ade 1 c++ containers templates stl stdvector

我正在尝试制作自己的迷你向量类,并且正在尝试复制一些函数,但是在传递诸如begin()和end()作为参数之类的调用时,我无法让它们以相同的方式运行 - 编译器不会推断出正确的版本。这是一个例子:

template<typename T>
class Iterator
{
public:
Iterator() {}
};

template<typename T>
class ConstIterator
{
public:
ConstIterator() {}
};

template <typename T>
class MyList {
   public:
    MyList() {}

    Iterator<T> Begin()
    {
        return Iterator<T>();
    }

    ConstIterator<T> Begin() const
    {
        return Iterator<T>();
    }

    void Insert(ConstIterator<T> it) 
    {

    }
};


int main() {
    MyList<int> myList;

    myList.Insert(myList.Begin());
}
Run Code Online (Sandbox Code Playgroud)

它myList.Insert(myList.Begin());不会尝试使用Begin()const 的正确版本。

据我在 std::vector 实现中所知,有两个版本的 begin() - 一个返回 an iterator,一个返回 a const_iterator。它们之间唯一的区别是一个是 const 方法(返回 const_iterator 的方法)。

_NODISCARD _CONSTEXPR20 iterator begin() noexcept {
    auto& _My_data = _Mypair._Myval2;
    return iterator(_My_data._Myfirst, _STD addressof(_My_data));
}

_NODISCARD _CONSTEXPR20 const_iterator begin() const noexcept {
    auto& _My_data = _Mypair._Myval2;
    return const_iterator(_My_data._Myfirst, _STD addressof(_My_data));
}
Run Code Online (Sandbox Code Playgroud)

许多方法,例如 std::vector::insert 都采用 const_iterator 参数:

_CONSTEXPR20 iterator insert(const_iterator _Where, const _Ty& _Val) { // insert _Val at _Where
    return emplace(_Where, _Val);
}

_CONSTEXPR20 iterator insert(const_iterator _Where, _Ty&& _Val) { // insert by moving _Val at _Where
    return emplace(_Where, _STD move(_Val));
}
Run Code Online (Sandbox Code Playgroud)

但是,insert 方法中没有任何内容可以使编译器使用 begin() 的 const 版本。这意味着它必须仅通过返回类型来推断,但据我所知这是不可能的?那么它是如何实现的呢?

use*_*522 6

没有扣除。如果myList不是- 限定的,则调用 的const非const版本。否则调用该版本。您如何使用结果并不相关。Begin()myList.Begin()constmyList.Begin()

标准库通过提供从非常量迭代器到常量迭代器的转换来避免您的问题。例如,您可以给出ConstIterator一个接受 a 的构造函数Iterator,无论如何您都必须拥有该构造函数才能return Iterator<T>();在您的工作const版本中进行声明Begin()(假设这不是拼写错误)。