Mar*_*rkB 1 c++ c++20 std-span
std::span考虑这段代码,它尝试为原始指针向量创建各种对象。
#include <vector>
#include <span>
int main()
{
struct S {};
std::vector<S*> v;
std::span<S*> span1{v};
std::span<S* const> span2{v};
std::span<const S* const> span3{v};
std::span<const S*> span4{v};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
span3编译正常,但span4失败并出现以下错误:
<source>: In function 'int main()':
<source>:58:32: error: no matching function for call to 'std::span<const main()::S*>::span(<brace-enclosed initializer list>)'
58 | std::span<const S*> span4{v};
| ^
In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:45,
from <source>:5:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/span:231:9: note: candidate: 'template<class _OType, long unsigned int _OExtent> requires (_Extent == std::dynamic_extent || _OExtent == std::dynamic_extent || _Extent == _OExtent) && (std::__is_array_convertible<_Type, _Tp>::value) constexpr std::span<_Type, _Extent>::span(const std::span<_OType, _OExtent>&) [with long unsigned int _OExtent = _OType; _Type = const main()::S*; long unsigned int _Extent = 18446744073709551615]'
Run Code Online (Sandbox Code Playgroud)
我要么期望span3两者span4都失败,要么两者都成功。有人可以解释为什么逻辑常量可以添加到std::span原始指针当且仅当底层指针是const(即按位)时。
std::span<const S*>允许您将 a 分配const S*给一个元素。std::vector<S*>允许您读取类型的元素S*。std::span<const S*>允许采用 a std::vector<S*>,那么可以通过将 a 分配给跨度的一个元素,然后通过向量读取相同的元素来偷偷地将 a 转换const S*为 a 。S*const S*也就是说,如果std::span<const S*> span4{v};允许,那么下面的程序将是有效的:
#include <vector>
#include <span>
int main()
{
struct S { int value; };
std::vector<S*> v = {nullptr};
std::span<const S*> span4{v}; // Note: not allowed in reality
const S s{.value = 0};
span4[0] = &s;
S* p = v[0];
assert(p == &s);
p->value = 42; // Oops, modifies the value of a const object!
}
Run Code Online (Sandbox Code Playgroud)
因此,为了防止这种情况并提供常量正确性,std::span<const S*>一定不能从std::vector<S*>.
另一方面,std::span<const S* const>不允许您分配给它的元素,因此它采用std::vector<S*>.
(是的,这与您可以将 a 转换S**为const S* const *,但不能将其转换为 的原因相同const S**。)
| 归档时间: |
|
| 查看次数: |
504 次 |
| 最近记录: |