如何将'const std::vector<T*>'转换为'std::span<const T*>'

How to convert `const std::vector<T*>` into `std::span<const T*>`

提问人:Carson 提问时间:10/16/2023 最后编辑:EvgCarson 更新时间:10/17/2023 访问量:157

问:

标题。

我正在实现这个类:

#include <span>
#include <vector>

class MyClass {
public:
    std::span<int *> numbers(void) {
        return m_numbers;
    }

    std::span<const int *> cnumbers(void) const {
        // What to do here?
    }

private:
    std::vector<int *> m_numbers;
};

我的第一次尝试是使用非常量函数中展示的自动转换(我相信这与?我真的不明白)。std:decay

return m_numbers

这无法编译,没有已知的转换。

我发现的一个实现是这样的:

return std::span(m_numbers.begin(), m_numbers.end());

这返回了一个,这并不完全是我想要的。这种用法的变体似乎无济于事。std::span<int * const>cbegin

我的目标是 c++20

C++ C++20 标准 std-span

评论

2赞 NathanOliver 10/16/2023
如果你使用会怎样?return std::span<const int *>(m_numbers.begin(), m_numbers.end());
0赞 Carson 10/16/2023
与第一种方法相同:error: no matching function for call to <full typenames>
0赞 NathanOliver 10/16/2023
好吧,如果你曾经尝试传播常量呢?return std::span<const int *>(m_numbers.cbegin(), m_numbers.cend());
3赞 Evg 10/16/2023
你试图打破 -correctness - propagagates -ness。你应该回来。conststd::vectorconststd::span<const int * const>
1赞 MarkB 10/17/2023
您可能还希望返回 的非常量重载numbers()std::span<int* const>

答:

8赞 Evg 10/16/2023 #1

你试图打破常量正确性。返回将允许修改这些元素(指针本身,这不会是)。std::span<const int *>const

正确的返回类型应为 ,请注意右侧的附加值。std::span<const int * const>const

评论

2赞 Chris 10/16/2023
也许值得澄清的是,这意味着指向 const int 的指针。指针本身可以更改,但不能更改它指向的值。while 表示不能更改为可以更改的 int 的指针。类型使两个方面。const int *int * constconst int * constconst
1赞 Ben Voigt 10/16/2023
实际上,成员函数与它无关。的所有者可以写入其指针的目标,因此它只能存储指向可写对象的指针。因此,即使是非成员函数也不允许使用指向只读对象的指针修改矢量元素。constvector<int*>intconst
0赞 Evg 10/17/2023
@BenVoigt我会尽力改进答案措辞,谢谢你的评论!
0赞 tmlen 10/17/2023
从技术上讲,获得 的一种方法是使用 .但它会破坏常量正确性,如果调用方修改指针,可能会导致 UB。std::span<const int*>auto begin = const_cast<const int**>(m_numbers.data()); return std::span<const int*>(begin, begin + m_numbers.size())