指向迭代器的 C++ 指针

C++ pointer to iterator

提问人:user3407352 提问时间:4/22/2022 最后编辑:Miles Budnekuser3407352 更新时间:4/22/2022 访问量:904

问:

我正在查看一些 20 年前的 C++ 代码,并试图使其保持最新状态。该代码上次是在 Visual Studio 2003 下编译的,我正在尝试使用 Visual Studio 2022 构建它。

我现在正在看一段无法编译的代码。我有一个.看起来 a 被传递给需要迭代器的方法。据我所知,指针和迭代器之间曾经存在隐式转换。这有什么意义吗?有人记得吗?std::vector<float>float*

C++ 指针 std 隐式转换

评论

4赞 n. m. could be an AI 4/22/2022
指针是一个迭代器,但指针和其他迭代器之间没有转换。从来没有。 可能与 相同,也可能不同。就是这样,有一个微不足道的转换。如果不是,则没有。它们是否相同可以在编译器版本之间、发布版本和调试版本之间或周五和周六之间发生变化。std::vector<float>::iteratorfloat*
4赞 Miles Budnek 4/22/2022
有标准的库实现,所以也许该代码在此类实现上出错。std::vector<T>::iteratorT*
0赞 user4581301 4/22/2022
这句话还算不太丑陋,但很好地提醒了我们,为什么一家公司应该每隔几年就把旧代码掸掉,并确保它仍然适用于新的工具链,并且在合理的情况下,遵循现代习语。
0赞 Karen Baghdasaryan 4/22/2022
The code was last compiled under visual studio 2003 and I am trying to build it with visual studio 2022,祝你好运,哥们;)
0赞 Etienne de Martel 4/22/2022
您能否展示一个无法编译的代码示例?

答:

1赞 Remy Lebeau 4/22/2022 #1

我有一个.看起来 a 被传递给需要迭代器的方法std::vector<float>float*

原始指针是有效的迭代器。迭代器旨在模拟指针。

因此,如果一个函数接受并传递了一个原始指针,它应该在所有版本的 C++ 中都能很好地编译。允许将迭代器实现为原始指针。iteratorstd::vector<T>T*

另一方面,如果一个函数接受一个原始指针并传递一个 ,则不能保证会编译,因为不需要将 作为原始指针实现,而且从来没有。您确定您的情况并非如此吗?iteratoriterator

评论

0赞 Etienne de Martel 4/23/2022
关于“从来没有”:IIRC,VS2003 实际上实现了向量迭代器作为指向指针的 typedef。这在 VS2005 中发生了变化。我会仔细检查它,但我现在无法访问 VS2003 安装。整个情况散发着“这个代码总是被破坏但偶然工作”的味道。
0赞 Remy Lebeau 4/23/2022
@EtiennedeMartel “VS2003 实际上将向量迭代器实现为指向指针的 typedef”——这是一个实现细节,而不是 C++ 标准规定的保证。“这个代码一直被破坏,但意外工作” - 同意。
0赞 Etienne de Martel 4/23/2022
啊,对了,我误读了你写的东西。
-2赞 Vero 4/22/2022 #2

我想我以前见过这个,我起草了下面的例子给你看一个例子,但请不要使用它(它的字面意思是 s***):

#include <iostream>
#include <vector>
#include <cassert>

struct Vector
{
    std::size_t m_size = 0;
    float* m_begin = nullptr;
    std::size_t size() const
    {
        return m_size;
    };
    
    void resize(const std::size_t n, float d = 0)
    {
        m_begin = (float*)malloc(n * sizeof(float));
        for(std::size_t i = 0; i < n; i++)
            *(m_begin + i) = d;
        m_size = n;
    };
    
    float& operator[](const std::size_t i) const
    {
        assert(i < m_size);
        return *(m_begin + i);
    }
};

void add(float* start, std::size_t size, float shift)
{
    for(std::size_t i = 0; i < size; i++)
        *(start + i) += shift;
}
int main() 
{
    Vector v;
    v.resize(3, 2);
    float& x = v[0];
    std::cout << x << std::endl;
    add(v.m_begin, v.m_size, 100);
    std::cout << x << std::endl;
    return 0;
}

作为输入的 takes 也适用于矩阵,即 .addfloat*float**

评论

0赞 Etienne de Martel 4/22/2022
呵呵,这里面有什么?这如何回答这个问题?std::vector
0赞 Vero 4/22/2022
std::vector<float> v;浮点数* 开始 = &v[0];这只是一个示例,说明如何将 float* 作为 arg 传递给函数:响应“It looks like a float* is passed to a method”。
0赞 Etienne de Martel 4/22/2022
是的,好吧,当然,但这不是新信息,也不是你刚刚分享的代码。超过 3/4 的代码与手头的问题无关(正如您所说,这也是非常糟糕的代码)。
0赞 Vero 4/22/2022
提出问题的人不确定,我选择展示完整的内容,也许他/她会从中挑选一些东西并找出他/她的代码。在所有情况下都不用担心:)
0赞 Etienne de Martel 4/23/2022
“full impl”是泄漏内存的代码,即使不需要它也会弄乱原始指针,尽管问题与迭代器有关,但甚至不包含迭代器用法,并且没有演示问题。它没有回答这个问题。std::vectorstd::vector