Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:在计算迭代器之间的距离时被类型所迷惑_C++_Algorithm_C++11_Iterator - Fatal编程技术网

C++ C++;:在计算迭代器之间的距离时被类型所迷惑

C++ C++;:在计算迭代器之间的距离时被类型所迷惑,c++,algorithm,c++11,iterator,C++,Algorithm,C++11,Iterator,我需要旋转std::vector中的元素,以便它在开始时保存第一个重复的元素。更清楚地说,如果我有: 1 2 3 4 5 6 3 7 8 那么我想: 3 4 5 6 3 7 8 1 2 好的,让我们使用std::rotate(),并构建一个函数来获取第一个重复位置: int main() { std::vector<int> v = { 1,2,3,4,5,6,3,7,8 }; auto it = FindFirstDuplicate(v); cout &

我需要旋转
std::vector
中的元素,以便它在开始时保存第一个重复的元素。更清楚地说,如果我有:

1 2 3 4 5 6 3 7 8
那么我想:

3 4 5 6 3 7 8 1 2   
好的,让我们使用
std::rotate()
,并构建一个函数来获取第一个重复位置:

int main() {
   std::vector<int> v = { 1,2,3,4,5,6,3,7,8 };
   auto it = FindFirstDuplicate(v);
   cout << "first dupe is " << *it << " at " << it - v.begin() << endl;
   std::rotate( v.begin(), it, v.end() );
}
为了节省您的时间,我没有发布错误消息,但对我来说,编译器似乎在最后一行抱怨不同类型的迭代器。我还尝试对
it1
使用非常量迭代器,但仍然遇到了这个问题


非常感谢您在迭代器问题上提供的任何帮助,以及关于算法本身的任何建议。

问题在于您试图从
常量
引用返回
迭代器
。您可以在这个最小的示例中看到问题:

#include <iostream>
#include <vector>

template <typename T>
typename std::vector<T>::iterator foo(const std::vector<T>& v)
{
    return v.begin(); // const overload returns const_iterator
}

int main() {
    std::vector<int> v(42);
    foo(v); // Instantiate function template: ERROR
}
#包括
#包括
模板
typename std::vector::迭代器foo(const std::vector&v)
{
return v.begin();//常量重载返回常量迭代器
}
int main(){
std::向量v(42);
foo(v);//实例化函数模板:错误
}
您可以做的是将非常量引用传递给finder函数:

template<typename T>
typename vector<T>::iterator FindFirstDuplicate( vector<T>& v )
{
   ...
模板
typename vector::迭代器FindFirstDuplicate(vector&v)
{
...

对于记录,正如@James Kanze(归功于他)所建议的,这里是一个较短、已更正且已完成的版本。此版本还返回找到的副本的位置

template<typename T>
typename vector<T>::iterator
FindFirstDuplicate( vector<T>& v, typename vector<T>::iterator& dupe )
{
   auto current = v.begin();
   while (
      current != v.end() &&
      (dupe = std::find( std::next( current ), v.end(), *current )) == v.end()
   )
   {
       ++current;
   }
   return current;
}

// test case
int main()
{   
   vector<int> v = { 1,2,3,4,5,6,5,4,3 };
   auto dupe = v.begin();
   auto it = FindFirstDuplicate(v,dupe);
   cout << "first dupe is " << *it << " at pos " << it - v.cbegin() << endl;
   cout << "dupe is " << *dupe << " at pos " << dupe - v.cbegin() << endl;
}
模板
类型名向量::迭代器
FindFirstDuplicate(vector&v,typename vector::iterator&dupe)
{
自动电流=v.开始();
当(
当前!=v.结束()&&
(dupe=std::find(std::next(当前),v.end(),*当前))==v.end()
)
{
++电流;
}
回流;
}
//测试用例
int main()
{   
向量v={1,2,3,4,5,6,5,4,3};
自动复制=v.开始();
自动it=FindFirstDuplicate(v,dupe);

findFirstDuplicate
中不需要临时向量吗?就像
while(current!=end&&std::find(std::next(current),end,*current)!=end){++current;}
就足够了(使用
current
end
初始化为
v.begin()
).好的,谢谢。但是如果我更愿意保留它只是为了可读性的目的,编译器难道不能优化它吗?我个人喜欢这样的想法,即不要试图自己对代码进行过度优化,并将其传递给编译器。我发现没有额外变量的版本更清晰:它非常清楚地表明您在同一个向量中寻找重复的代码(而不是其他地方)并且它避免了复杂的迭代器算法来确定返回值。@James Kanze好的,我明白了,我会试试。我只是不熟悉
std::next()
,所以我一眼就不太清楚。但我喜欢学习新技巧,谢谢!@James Kanze我发布了你建议的完整版本,只做了一点小小的修改,谢谢。哇,太简单了……我被(像往常一样)过于冗长的错误消息愚弄了,甚至没有考虑检查参数constness。谢谢。
template<typename T>
typename vector<T>::iterator
FindFirstDuplicate( vector<T>& v, typename vector<T>::iterator& dupe )
{
   auto current = v.begin();
   while (
      current != v.end() &&
      (dupe = std::find( std::next( current ), v.end(), *current )) == v.end()
   )
   {
       ++current;
   }
   return current;
}

// test case
int main()
{   
   vector<int> v = { 1,2,3,4,5,6,5,4,3 };
   auto dupe = v.begin();
   auto it = FindFirstDuplicate(v,dupe);
   cout << "first dupe is " << *it << " at pos " << it - v.cbegin() << endl;
   cout << "dupe is " << *dupe << " at pos " << dupe - v.cbegin() << endl;
}