gpt4 book ai didi

c++ - 我已经编写了 C++ 代码来将 boost::optional 视为一个范围,但它无法编译

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:25 31 4
gpt4 key购买 nike

我希望将 boost::optional 视为一个容器,其中可以包含零个或一个元素。从逻辑上讲,我应该能够为容器创建一个迭代器并在其上使用 boost::for_each。我的尝试如下,但无法编译。我已经在 GodBolt 上试过了。

https://godbolt.org/g/z5MFfe

下面的代码供引用。

#include <boost/optional.hpp>
#include <boost/range.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <iostream>

namespace boost {

template <typename OT>
class optional_iterator
: public boost::iterator_facade<optional_iterator<OT>,
typename OT::value_type,
boost::forward_traversal_tag> {
private:
OT m_o;

public:
optional_iterator() : m_o(boost::none) {}
explicit optional_iterator(OT& o) : m_o(o) {}

private:
friend class boost::iterator_core_access;

void increment() { m_o = boost::none; }

bool equal(OT& other) const { return this->m_o == other.m_o; }

typename OT::value_type& dereference() { return *m_o; }
};

template <typename T>
struct optional_iterators {
typedef optional_iterator<boost::optional<T>> iterator;
typedef optional_iterator<boost::optional<T> const> const_iterator;
};

template <class T>
struct range_mutable_iterator<boost::optional<T>> {
typedef typename optional_iterators<T>::iterator type;
};

template <class T>
struct range_const_iterator<boost::optional<T> const> {
typedef typename optional_iterators<T const>::const_iterator type;
};

template <class T>
inline typename optional_iterators<T>::iterator range_begin(
boost::optional<T>& x) {
return typename optional_iterators<T>::iterator(x);
}

template <class T>
inline typename optional_iterators<T>::const_iterator range_begin(
boost::optional<T> const& x) {
return typename optional_iterators<T>::const_iterator(x);
}

template <class T>
inline typename optional_iterators<T>::iterator range_end(boost::optional<T>&x) {
return typename optional_iterators<T>::iterator();
}

template <class T>
inline typename optional_iterators<T>::const_iterator range_end(boost::optional<T> const & x) {
return typename optional_iterators<T>::const_iterator();
}
} // namespace boost

int main() {
auto a = boost::optional<int>(10);
auto rb = range_begin(a);
auto re = range_end(a);

boost::for_each(a, [](int const& i) { std::cout << i; });
}

我很确定我已经正确地实现了范围和迭代器的概念,但是我在 gcc 8.1 中遇到了以下编译器错误(根据 godbolt)

#1 with x86-64 gcc 8.1
In file included from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/size_type.hpp:20,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/size.hpp:21,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/functions.hpp:20,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/range.hpp:18,

from <source>:3:

/opt/compiler-explorer/libs/boost_1_64_0/boost/range/concepts.hpp: In instantiation of 'struct boost::SinglePassRangeConcept<boost::optional<int> >':

/opt/compiler-explorer/libs/boost_1_64_0/boost/concept/detail/has_constraints.hpp:32:62: required by substitution of 'template<class Model> boost::concepts::detail::yes boost::concepts::detail::has_constraints_(Model*, boost::concepts::detail::wrap_constraints<Model, (& Model::constraints)>*) [with Model = boost::SinglePassRangeConcept<boost::optional<int> >]'

/opt/compiler-explorer/libs/boost_1_64_0/boost/concept/detail/has_constraints.hpp:42:5: required from 'const bool boost::concepts::not_satisfied<boost::SinglePassRangeConcept<boost::optional<int> > >::value'

/opt/compiler-explorer/libs/boost_1_64_0/boost/concept/detail/has_constraints.hpp:45:31: required from 'struct boost::concepts::not_satisfied<boost::SinglePassRangeConcept<boost::optional<int> > >'

/opt/compiler-explorer/libs/boost_1_64_0/boost/mpl/if.hpp:63:11: required from 'struct boost::mpl::if_<boost::concepts::not_satisfied<boost::SinglePassRangeConcept<boost::optional<int> > >, boost::concepts::constraint<boost::SinglePassRangeConcept<boost::optional<int> > >, boost::concepts::requirement<boost::concepts::failed************ boost::SinglePassRangeConcept<boost::optional<int> >::************> >'

/opt/compiler-explorer/libs/boost_1_64_0/boost/concept/detail/general.hpp:51:8: required from 'struct boost::concepts::requirement_<void (*)(boost::SinglePassRangeConcept<boost::optional<int> >)>'

/opt/compiler-explorer/libs/boost_1_64_0/boost/range/size.hpp:62:9: required from 'UnaryFunction boost::range::for_each(SinglePassRange&, UnaryFunction) [with SinglePassRange = boost::optional<int>; UnaryFunction = main()::<lambda(const int&)>]'

<source>:75:59: required from here

/opt/compiler-explorer/libs/boost_1_64_0/boost/range/concepts.hpp:272:17: error: no type named 'type' in 'struct boost::range_iterator<const boost::optional<int>, void>'

>::type const_iterator;

^~~~~~~~~~~~~~

In file included from /opt/compiler-explorer/libs/boost_1_64_0/boost/concept/assert.hpp:35,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/concept_check.hpp:20,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/concepts.hpp:19,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/size_type.hpp:20,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/size.hpp:21,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/functions.hpp:20,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/range.hpp:18,

from <source>:3:

/opt/compiler-explorer/libs/boost_1_64_0/boost/range/concepts.hpp:279:9: error: no type named 'type' in 'struct boost::range_iterator<const boost::optional<int>, void>'

BOOST_RANGE_CONCEPT_ASSERT((

^~~~~~~~~~~~~~~~~~~~~~~~~~

In file included from /opt/compiler-explorer/gcc-8.1.0/include/c++/8.1.0/algorithm:62,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/core/swap.hpp:25,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/optional/optional.hpp:27,

from /opt/compiler-explorer/libs/boost_1_64_0/boost/optional.hpp:15,

from <source>:2:

/opt/compiler-explorer/gcc-8.1.0/include/c++/8.1.0/bits/stl_algo.h:3876:5: error: '_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = boost::optional_iterator<boost::optional<int> >; _Funct = main()::<lambda(const int&)>]', declared using local type 'main()::<lambda(const int&)>', is used but never defined [-fpermissive]

for_each(_InputIterator __first, _InputIterator __last, _Function __f)

^~~~~~~~

/opt/compiler-explorer/gcc-8.1.0/include/c++/8.1.0/bits/stl_algo.h:3876:5: warning: '_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = boost::optional_iterator<boost::optional<int> >; _Funct = main()::<lambda(const int&)>]' used but never defined

Compiler returned: 1

最佳答案

我会保持简单:

template <typename T> auto make_range(optional<T>& opt) {
T* addr = opt? std::addressof(*opt) : nullptr;
return make_iterator_range(addr, opt? addr+1 : addr);
}

我还没有测试过这个,但它看起来很简单,也许可以正常工作。

关于c++ - 我已经编写了 C++ 代码来将 boost::optional 视为一个范围,但它无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51036886/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com