Reputation: 4848
Let's preface it by stating once again that std::vector<bool>
was a mistake.
But now it finally bit me. This doesn't compile:
#include <iostream>
#include <span>
#include <vector>
#include <cstdint>
int main()
{
std::vector<uint8_t> intvec = { 1, 2, 3, 4 };
auto vec_int_view = std::span(intvec);
// This will not compile:
// std::vector<bool> boolvec = { true, false, true, true };
// auto vec_bool_view = std::span(boolvec);
}
Errors:
<source>: In function 'int main()':
<source>:13:43: error: class template argument deduction failed:
13 | auto vec_bool_view = std::span(boolvec);
| ^
<source>:13:43: error: no matching function for call to 'span(std::vector<bool>&)'
In file included from <source>:2:
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:233:9: note: candidate: 'template<class _Type, long unsigned int _Extent, class _OType, long unsigned int _OExtent> requires (_Extent == std::dynamic_extent || _OExtent == std::dynamic_extent || _Extent == _OExtent) && (std::__is_array_convertible<_Type, _OType>::value) span(const std::span<_OType, _OExtent>&)-> std::span<_Type, _Extent>'
233 | span(const span<_OType, _OExtent>& __s) noexcept
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:233:9: note: template argument deduction/substitution failed:
<source>:13:43: note: 'std::vector<bool>' is not derived from 'const std::span<_OType, _OExtent>'
13 | auto vec_bool_view = std::span(boolvec);
| ^
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:225:7: note: candidate: 'template<class _Type, long unsigned int _Extent> span(const std::span<_Tp, _Num>&)-> std::span<_Type, _Extent>'
225 | span(const span&) noexcept = default;
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:225:7: note: template argument deduction/substitution failed:
<source>:13:43: note: 'std::vector<bool>' is not derived from 'const std::span<_Tp, _Num>'
13 | auto vec_bool_view = std::span(boolvec);
| ^
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:213:9: note: candidate: 'template<class _Type, long unsigned int _Extent, class _Range> requires !(__is_span<typename std::remove_cvref<_I2>::type>) && !(__is_std_array<typename std::remove_cvref<_I2>::type>) && !(is_array_v<typename std::remove_cvref<_I2>::type>) && (contiguous_range<_Range>) && (sized_range<_Range>) && ((borrowed_range<_Range>) || (is_const_v<_Type>)) && (std::__is_compatible_ref<decltype(*(declval<decltype(std::ranges::__access::__begin((declval<_Range&>)()))&>)())>::value) span(_Range&&)-> std::span<_Type, _Extent>'
213 | span(_Range&& __range)
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:213:9: note: template argument deduction/substitution failed:
<source>:13:43: note: couldn't deduce template parameter '_Type'
13 | auto vec_bool_view = std::span(boolvec);
| ^
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:201:9: note: candidate: 'template<class _Type, long unsigned int _Extent, class _Tp, long unsigned int _ArrayExtent> requires std::span<_Tp, _Num>::__is_compatible_array::value span(const std::array<_Tp, _ArrayExtent>&)-> std::span<_Type, _Extent>'
201 | span(const array<_Tp, _ArrayExtent>& __arr) noexcept
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:201:9: note: template argument deduction/substitution failed:
<source>:13:43: note: 'std::vector<bool>' is not derived from 'const std::array<_Tp, _ArrayExtent>'
13 | auto vec_bool_view = std::span(boolvec);
| ^
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:194:9: note: candidate: 'template<class _Type, long unsigned int _Extent, class _Tp, long unsigned int _ArrayExtent> requires std::span<_Tp, _Num>::__is_compatible_array::value span(std::array<_Tp, _ArrayExtent>&)-> std::span<_Type, _Extent>'
194 | span(array<_Tp, _ArrayExtent>& __arr) noexcept
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:194:9: note: template argument deduction/substitution failed:
<source>:13:43: note: 'std::vector<bool>' is not derived from 'std::array<_Tp, _ArrayExtent>'
13 | auto vec_bool_view = std::span(boolvec);
| ^
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:187:9: note: candidate: 'template<class _Type, long unsigned int _Extent, long unsigned int _ArrayExtent> requires _Extent == std::dynamic_extent || _ArrayExtent == _Extent span(std::type_identity_t<_Type> (&)[_ArrayExtent])-> std::span<_Type, _Extent>'
187 | span(type_identity_t<element_type> (&__arr)[_ArrayExtent]) noexcept
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:187:9: note: template argument deduction/substitution failed:
<source>:13:43: note: mismatched types 'std::type_identity_t<_Type> [_ArrayExtent]' and 'std::vector<bool>'
13 | auto vec_bool_view = std::span(boolvec);
| ^
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:172:9: note: candidate: 'template<class _Type, long unsigned int _Extent, class _It, class _End> requires (contiguous_iterator<_It>) && (sized_sentinel_for<_End, _It>) && ((std::__is_compatible_ref<decltype(*(declval<_I2&>)())>::value) && !(is_convertible_v<_End, long unsigned int>)) span(_It, _End)-> std::span<_Type, _Extent>'
172 | span(_It __first, _End __last)
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:172:9: note: candidate expects 2 arguments, 1 provided
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:157:9: note: candidate: 'template<class _Type, long unsigned int _Extent, class _It> requires (contiguous_iterator<_It>) && (std::__is_compatible_ref<decltype(*(declval<_I2&>)())>::value) span(_It, std::size_t)-> std::span<_Type, _Extent>'
157 | span(_It __first, size_type __count)
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:157:9: note: candidate expects 2 arguments, 1 provided
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:149:7: note: candidate: 'template<class _Type, long unsigned int _Extent> span()-> std::span<_Type, _Extent> requires _Extent == std::dynamic_extent || _Extent == 0'
149 | span() noexcept
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:149:7: note: candidate expects 0 arguments, 1 provided
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:54:11: note: candidate: 'template<class _Type, long unsigned int _Extent> span(std::span<_Type, _Extent>)-> std::span<_Type, _Extent>'
54 | class span;
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:54:11: note: template argument deduction/substitution failed:
<source>:13:43: note: 'std::vector<bool>' is not derived from 'std::span<_Type, _Extent>'
13 | auto vec_bool_view = std::span(boolvec);
| ^
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:466:5: note: candidate: 'template<class _Range> requires contiguous_range<_Range> std::span(_Range&&)-> span<typename remove_reference<ranges::range_reference_t<_Range&> >::type>'
466 | span(_Range &&)
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:466:5: note: template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:466:5: note: constraints not satisfied
In file included from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/compare:40,
from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/char_traits.h:56,
from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/ios:42,
from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/ostream:40,
from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/iostream:41,
from <source>:1:
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/concepts: In substitution of 'template<class _Range> requires contiguous_range<_Range> std::span(_Range&&)-> span<typename remove_reference<ranges::range_reference_t<_Range&> >::type> [with _Range = std::vector<bool>&]':
<source>:13:43: required from here
13 | auto vec_bool_view = std::span(boolvec);
| ^
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/concepts:74:13: required for the satisfaction of 'derived_from<typename std::__detail::__iter_concept_impl<_Iter>::type, std::contiguous_iterator_tag>' [with _Iter = std::_Bit_iterator]
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/iterator_concepts.h:697:13: required for the satisfaction of 'contiguous_iterator<decltype (std::ranges::__access::__begin(declval<_Container&>()))>' [with _Tp = std::vector<bool, std::allocator<bool> >&]
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/ranges_base.h:607:13: required for the satisfaction of 'contiguous_range<_Range>' [with _Range = std::vector<bool, std::allocator<bool> >&]
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/concepts:74:28: note: 'std::contiguous_iterator_tag' is not a base of 'std::random_access_iterator_tag'
74 | concept derived_from = __is_base_of(_Base, _Derived)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:462:5: note: candidate: 'template<class _Iter, class _End> requires contiguous_iterator<_Iter> std::span(_Iter, _End)-> span<typename remove_reference<iter_reference_t<_Tp> >::type>'
462 | span(_Iter, _End)
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:462:5: note: candidate expects 2 arguments, 1 provided
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:458:5: note: candidate: 'template<class _Type, long unsigned int _ArrayExtent> std::span(const array<_Tp, _Nm>&)-> span<const _Type, _ArrayExtent>'
458 | span(const array<_Type, _ArrayExtent>&)
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:458:5: note: template argument deduction/substitution failed:
<source>:13:43: note: 'std::vector<bool>' is not derived from 'const std::array<_Tp, _Nm>'
13 | auto vec_bool_view = std::span(boolvec);
| ^
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:455:5: note: candidate: 'template<class _Type, long unsigned int _ArrayExtent> std::span(array<_Tp, _Nm>&)-> span<_Tp, _Num>'
455 | span(array<_Type, _ArrayExtent>&) -> span<_Type, _ArrayExtent>;
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:455:5: note: template argument deduction/substitution failed:
<source>:13:43: note: 'std::vector<bool>' is not derived from 'std::array<_Tp, _Nm>'
13 | auto vec_bool_view = std::span(boolvec);
| ^
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:452:5: note: candidate: 'template<class _Type, long unsigned int _ArrayExtent> std::span(_Type (&)[_ArrayExtent])-> span<_Tp, _Num>'
452 | span(_Type(&)[_ArrayExtent]) -> span<_Type, _ArrayExtent>;
| ^~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:452:5: note: template argument deduction/substitution failed:
<source>:13:43: note: mismatched types '_Type [_ArrayExtent]' and 'std::vector<bool>'
13 | auto vec_bool_view = std::span(boolvec);
| ^
What are my options here? Just use std::vector<uint8_t>
?
I almost thought I could finally make use of this vector
optimisation.. :/
Upvotes: 2
Views: 189
Reputation: 29009
describes an object that can refer to a contiguous sequence of objects with the first element of the sequence at position zero.
This means std::span<T>
can refer to a contigous sequences of T
s.
However std::vector<bool>
:
Does not necessarily store its elements as a contiguous array.
So the two do not match.
Morover - std::vector<bool>
is not a proper std container at all, since it does not guarantee all the Container requirements.
If it's important for you to use a span
into the sequence, I would go with std::vector<uint8_t>
.
If it's not a must, and you want to keep memory footprint compact, you can have a look at std::bitset
.
In any case I would not use std::vector<bool>
if I have a choice.
See more about it here: Is the use of std::vector<bool>
objects in C++ acceptable, or should I use an alternative?.
Upvotes: 5