gpt4 book ai didi

c++ - auto it = vector.begin() 结果类型不可转换为 const_iterator

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:54:48 26 4
gpt4 key购买 nike

容器需要提供 iterator可隐式转换为 const_iterator 的类型.鉴于此,我正在尝试使用 auto通过 vector::begin() 初始化对象,并在 std::distance 中使用该结果对象其中 RHS 是 const_iterator .这是行不通的。这是一个完整的例子:

#include <cstdlib>
#include <vector>
#include <iterator>
#include <iostream>

typedef std::vector <char> Packet;
typedef std::vector <Packet> Packets;

template <typename Iter>
Iter next_upto (Iter begin, Iter end, size_t n)
{
Iter ret = begin;
for (; n > 0 && ret != end; ++ret, --n)
;
return ret;
}

Packets::const_iterator Process (Packets::const_iterator begin, Packets::const_iterator end)
{
Packets::const_iterator ret = begin;
while (ret != end)
++ret; // do something
return ret;
}

int main()
{
Packets test (100); // vector of 100 default-initialized packets

// process them 10 at a time
for (auto it = test.begin();
it != test.end();
it = next_upto (it, test.end(), 10))
{
auto itr = Process (it, next_upto (it, test.end(), 10));
Packets::const_iterator it2 = it;
const size_t n1 = std::distance (it2, itr);
const size_t n = std::distance (it, itr);
std::cout << "Processed " << n << " packets\n";
}
}

在 g++ 4.8.1(和 4.8.2)下编译会产生:

[1/2] Building CXX object CMakeFiles/hacks.dir/main.o
FAILED: /usr/bin/g++ -Wall -std=c++11 -g -MMD -MT CMakeFiles/hacks.dir/main.o -MF "CMakeFiles/hacks.dir/main.o.d" -o CMakeFiles/hacks.dir/main.o -c main.cpp
main.cpp: In function ‘int main()’:
main.cpp:39:45: error: no matching function for call to ‘distance(__gnu_cxx::__normal_iterator<std::vector<char>*, std::vector<std::vector<char> > >&, __gnu_cxx::__normal_iterator<const std::vector<char>*, std::vector<std::vector<char> > >&)’
const size_t n = std::distance (it, itr);
^
main.cpp:39:45: note: candidate is:
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:66:0,
from /usr/include/c++/4.8/vector:60,
from main.cpp:2:
/usr/include/c++/4.8/bits/stl_iterator_base_funcs.h:114:5: note: template<class _InputIterator> typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator)
distance(_InputIterator __first, _InputIterator __last)
^
/usr/include/c++/4.8/bits/stl_iterator_base_funcs.h:114:5: note: template argument deduction/substitution failed:
main.cpp:39:45: note: deduced conflicting types for parameter ‘_InputIterator’ (‘__gnu_cxx::__normal_iterator<std::vector<char>*, std::vector<std::vector<char> > >’ and ‘__gnu_cxx::__normal_iterator<const std::vector<char>*, std::vector<std::vector<char> > >’)
const size_t n = std::distance (it, itr);
^

我知道我可以通过调用 cbegin() 来修复这个特定的实例和 cend()而不是 begin()end() , 但自 begin()end()返回应可转换为 const_iterator 的类型,我不确定我是否理解为什么需要这样做。

为什么 auto在这种情况下推导出一个不可转换为 const_iterator 的类型?

最佳答案

您的问题可以简化为以下示例,但由于相同的原因而失败。

#include <vector>
#include <iterator>
int main()
{
std::vector<int> v;
std::vector<int>::const_iterator it1 = v.begin();
auto it2 = v.end();
auto n = std::distance(it1, it2);
}

std::distance为两个参数使用相同的模板参数类型定义,并且模板参数推导失败,因为您有一个 const_iteratoriterator

从函数调用推导模板参数时不考虑用户定义的转换,并且由于在这种情况下两个参数具有不同的类型,并且都参与模板参数推导,推导失败。

§14.8.1/6 [temp.arg.explicit]

Implicit conversions (Clause 4) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template-parameters that participate in template argument deduction.

§14.8.2.1/4 [温度过高]

... [ Note: as specified in 14.8.1, implicit conversions will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter contains no template-parameters that participate in template argument deduction. Such conversions are also allowed, in addition to the ones described in the preceding list. —end note ]

您需要将 iterator 转换为 const_iterator,或明确指定 std::distance 的模板参数。

auto n = std::distance(it1, static_cast<decltype(it1)>(it2));

auto n = std::distance<decltype(it1)>(it1, it2);

当然,其他选项是不使用 auto 并在两种情况下显式指定迭代器类型,或者使用 vector::cbegin()vector::cend() 成员函数,当您需要确保类型是 const_iterator 时。

关于c++ - auto it = vector.begin() 结果类型不可转换为 const_iterator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25184932/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com