boostorg / boostorg/fusion

Dereferencing `boost::fusion::vector<>`'s iterator is not SFINAE-friendly

Open
#278 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
C++
Stars
50
Forks
68
PR merge metrics
No merged PRs in 30d

Description

Consider following code:
```cpp
#include

#include

template
struct is_dereferenceable : std::false_type {};

template
struct is_dereferenceable())> : std::true_type {};

using empty_vector = boost::fusion::vector<>;
using empty_vector_iterator = boost::fusion::result_of::begin::type;
static_assert(!is_dereferenceable::value);

int main() {}
```

This code should compile successfully, guaranteeing `empty_vector_iterator` is never dereferenceable.
However, this emits following hard errors:
```
In file included from /usr/include/boost/fusion/container/vector.hpp:10,
from source.cpp:1:
/usr/include/boost/fusion/container/vector/detail/value_at_impl.hpp: In instantiation of ‘struct boost::fusion::extension::value_at_impl::apply, mpl_::int_<0> >’:
/usr/include/boost/fusion/container/vector/detail/deref_impl.hpp:33:97: required from ‘struct boost::fusion::extension::deref_impl::apply, 0> >’
/usr/include/boost/fusion/iterator/deref.hpp:51:16: required from ‘struct boost::fusion::result_of::deref, 0> >’
/usr/include/boost/fusion/iterator/deref.hpp:69:5: required by substitution of ‘template constexpr typename boost::fusion::result_of::deref::type boost::fusion::operator*(const iterator_base&) [with Iterator = boost::fusion::vector_iterator, 0>]’
source.cpp:9:46: required by substitution of ‘template struct is_dereferenceable())> [with Iterator = boost::fusion::vector_iterator, 0>]’
source.cpp:13:57: required from here
/usr/include/boost/fusion/container/vector/detail/value_at_impl.hpp:50:28: error: no matching function for call to ‘value_at_impl::value>(boost::fusion::vector<>*)’
50 | struct apply : BOOST_FUSION_DECLTYPE_N3031((
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/fusion/container/vector/detail/at_impl.hpp:12,
from /usr/include/boost/fusion/container/vector/vector.hpp:29,
from /usr/include/boost/fusion/container/vector.hpp:12:
/usr/include/boost/fusion/container/vector/detail/value_at_impl.hpp:38:26: note: candidate: ‘template boost::mpl::identity boost::fusion::vector_detail::value_at_impl(const volatile store*)’
38 | mpl::identity value_at_impl(store const volatile*);
| ^~~~~~~~~~~~~
/usr/include/boost/fusion/container/vector/detail/value_at_impl.hpp:38:26: note: template argument deduction/substitution failed:
/usr/include/boost/fusion/container/vector/detail/value_at_impl.hpp:50:28: note: ‘boost::fusion::vector<>’ is not derived from ‘const volatile boost::fusion::vector_detail::store<0, U>’
50 | struct apply : BOOST_FUSION_DECLTYPE_N3031((
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/fusion/container/vector/vector_iterator.hpp:12,
from /usr/include/boost/fusion/container/vector/detail/begin_impl.hpp:11,
from /usr/include/boost/fusion/container/vector/vector.hpp:31:
/usr/include/boost/fusion/container/vector/detail/deref_impl.hpp: In instantiation of ‘struct boost::fusion::extension::deref_impl::apply, 0> >’:
/usr/include/boost/fusion/iterator/deref.hpp:51:16: required from ‘struct boost::fusion::result_of::deref, 0> >’
/usr/include/boost/fusion/iterator/deref.hpp:69:5: required by substitution of ‘template constexpr typename boost::fusion::result_of::deref::type boost::fusion::operator*(const iterator_base&) [with Iterator = boost::fusion::vector_iterator, 0>]’
source.cpp:9:46: required by substitution of ‘template struct is_dereferenceable())> [with Iterator = boost::fusion::vector_iterator, 0>]’
source.cpp:13:57: required from here
/usr/include/boost/fusion/container/vector/detail/deref_impl.hpp:33:97: error: no type named ‘type’ in ‘struct boost::fusion::extension::value_at_impl::apply, mpl_::int_<0> >’
33 | typedef typename value_at_impl::template apply::type element;
| ^~~~~~~
/usr/include/boost/fusion/container/vector/detail/deref_impl.hpp:41:17: error: no type named ‘type’ in ‘struct boost::fusion::extension::value_at_impl::apply, mpl_::int_<0> >’
41 | type;
| ^~~~

```

This breaks some existing constrained codes.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the reported instantiation path in boost/fusion/container/vector/detail/value_at_impl.hpp and boost/fusion/container/vector/detail/deref_impl.hpp, then inspect the dereference entry point in boost/fusion/iterator/deref.hpp. Use the empty-vector reproducer from the issue and verify that its static assertion compiles without hard errors while non-dereferenceability remains detected.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
developer-experience
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.