c++ - 在std::unique_ptr的 vector 上使用make_transform_iterator获取const指针

标签 c++ boost c++17 boost-iterators

我想创建一个类,其中包含一个数据结构的unique_ptr vector ,并且可以作为指向数据结构的const指针进行迭代。
我尝试了这段代码,但没有成功:

#include <iostream>
#include <vector>
#include <memory>

#include <boost/compute/iterator/transform_iterator.hpp>

struct data final {

  data(int val) : _value(val) {
  }

  int value() const {
    return _value;
  }

private:
  int _value;
};

const data* get_value(const std::unique_ptr<data>& item) {
  return item.get();
}

struct wrapped {
  wrapped(std::vector<std::unique_ptr<data>> &&items) : _items(std::move(items)) {
  }

  auto begin() const {
    return boost::compute::make_transform_iterator(_items.begin(), &get_value);
  }

  auto end() const {
    return boost::compute::make_transform_iterator(_items.end(), &get_value);
  }

private:
  std::vector<std::unique_ptr<data>> _items;
};

int main() {

  std::vector<std::unique_ptr<data>> vec;
  vec.emplace_back(std::make_unique<data>(42));

  wrapped wvec(std::move(vec));

  for(const auto &ptr : wvec) {
    std::cout << ptr->value() << std::endl;
  }
}
我还尝试过将lambda封装在get_value的函数中,但没有取得更大的成功:
std::function<const data*(const std::unique_ptr<data>&)> func = [](const std::unique_ptr<data>& item) -> const data* {
  return item.get();
};

// then inside struct wrapped:

auto begin() const {
  return boost::compute::make_transform_iterator(_items.begin(), func);
}

auto end() const {
  return boost::compute::make_transform_iterator(_items.end(), func);
}
在这两种情况下,我都遇到相同的编译错误,但是我不太了解它们。
为什么不编译,以及如何更正呢?
编辑:添加编译错误:
In file included from test-transform-iterator.cc:8:
/usr/local/include/boost/compute/iterator/transform_iterator.hpp:177:53: error: no member named 'get_buffer' in 'std::__1::__wrap_iter<const std::__1::unique_ptr<data, std::__1::default_delete<data> > *>'
        const context &context = super_type::base().get_buffer().get_context();
                                 ~~~~~~~~~~~~~~~~~~ ^
/usr/local/include/boost/iterator/iterator_facade.hpp:550:20: note: in instantiation of member function 'boost::compute::transform_iterator<std::__1::__wrap_iter<const std::__1::unique_ptr<data, std::__1::default_delete<data> > *>, std::__1::function<const data *(const std::__1::unique_ptr<data,
      std::__1::default_delete<data> > &)> >::dereference' requested here
          return f.dereference();
                   ^
/usr/local/include/boost/iterator/iterator_facade.hpp:656:42: note: in instantiation of function template specialization 'boost::iterators::iterator_core_access::dereference<boost::compute::transform_iterator<std::__1::__wrap_iter<const std::__1::unique_ptr<data, std::__1::default_delete<data> >
      *>, std::__1::function<const data *(const std::__1::unique_ptr<data, std::__1::default_delete<data> > &)> > >' requested here
            return iterator_core_access::dereference(this->derived());
                                         ^
test-transform-iterator.cc:56:23: note: in instantiation of member function 'boost::iterators::detail::iterator_facade_base<boost::compute::transform_iterator<std::__1::__wrap_iter<const std::__1::unique_ptr<data, std::__1::default_delete<data> > *>, std::__1::function<const data *(const
      std::__1::unique_ptr<data, std::__1::default_delete<data> > &)> >, const data *, std::__1::random_access_iterator_tag, const data *, long, false, false>::operator*' requested here
  for(const auto &ptr : wvec) {
                      ^
In file included from test-transform-iterator.cc:8:
/usr/local/include/boost/compute/iterator/transform_iterator.hpp:182:42: error: no viable overloaded operator[] for type 'const std::__1::__wrap_iter<const std::__1::unique_ptr<data, std::__1::default_delete<data> > *>'
        k << "*output = " << m_transform(super_type::base()[k.lit(0)]) << ";";
                                         ^~~~~~~~~~~~~~~~~~ ~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iterator:1512:73: note: candidate function not viable: no known conversion from 'detail::meta_kernel_literal<int>' to 'std::__1::__wrap_iter<const std::__1::unique_ptr<data,
      std::__1::default_delete<data> > *>::difference_type' (aka 'long') for 1st argument
    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference    operator[](difference_type __n) const _NOEXCEPT
                                                                        ^
In file included from test-transform-iterator.cc:8:
In file included from /usr/local/include/boost/compute/iterator/transform_iterator.hpp:20:
In file included from /usr/local/include/boost/compute/functional.hpp:19:
In file included from /usr/local/include/boost/compute/functional/atomic.hpp:15:
In file included from /usr/local/include/boost/compute/function.hpp:33:
/usr/local/include/boost/compute/type_traits/type_name.hpp:98:20: error: implicit instantiation of undefined template 'boost::compute::detail::type_name_trait<const data *>'
    return detail::type_name_trait<T>::value();
                   ^
/usr/local/include/boost/compute/detail/meta_kernel.hpp:485:19: note: in instantiation of function template specialization 'boost::compute::type_name<const data *>' requested here
        stream << type_name<Type>();
                  ^
/usr/local/include/boost/compute/detail/meta_kernel.hpp:409:19: note: in instantiation of function template specialization 'boost::compute::detail::meta_kernel::type<const data **>' requested here
        stream << type<T>() << " " << name;
                  ^
/usr/local/include/boost/compute/detail/meta_kernel.hpp:942:24: note: in instantiation of function template specialization 'boost::compute::detail::meta_kernel::add_arg<const data **>' requested here
        size_t index = add_arg<T>(name);
                       ^
/usr/local/include/boost/compute/detail/meta_kernel.hpp:422:16: note: in instantiation of function template specialization 'boost::compute::detail::meta_kernel::add_arg_with_qualifiers<const data **>' requested here
        return add_arg_with_qualifiers<T>(address_space_prefix(address_space), name);
               ^
/usr/local/include/boost/compute/iterator/transform_iterator.hpp:181:31: note: in instantiation of function template specialization 'boost::compute::detail::meta_kernel::add_arg<const data **>' requested here
        size_t output_arg = k.add_arg<value_type *>(memory_object::global_memory, "output");
                              ^
/usr/local/include/boost/iterator/iterator_facade.hpp:550:20: note: in instantiation of member function 'boost::compute::transform_iterator<std::__1::__wrap_iter<const std::__1::unique_ptr<data, std::__1::default_delete<data> > *>, std::__1::function<const data *(const std::__1::unique_ptr<data,
      std::__1::default_delete<data> > &)> >::dereference' requested here
          return f.dereference();
                   ^
/usr/local/include/boost/iterator/iterator_facade.hpp:656:42: note: in instantiation of function template specialization 'boost::iterators::iterator_core_access::dereference<boost::compute::transform_iterator<std::__1::__wrap_iter<const std::__1::unique_ptr<data, std::__1::default_delete<data> >
      *>, std::__1::function<const data *(const std::__1::unique_ptr<data, std::__1::default_delete<data> > &)> > >' requested here
            return iterator_core_access::dereference(this->derived());
                                         ^
test-transform-iterator.cc:56:23: note: in instantiation of member function 'boost::iterators::detail::iterator_facade_base<boost::compute::transform_iterator<std::__1::__wrap_iter<const std::__1::unique_ptr<data, std::__1::default_delete<data> > *>, std::__1::function<const data *(const
      std::__1::unique_ptr<data, std::__1::default_delete<data> > &)> >, const data *, std::__1::random_access_iterator_tag, const data *, long, false, false>::operator*' requested here
  for(const auto &ptr : wvec) {
                      ^
/usr/local/include/boost/compute/type_traits/type_name.hpp:24:8: note: template is declared here
struct type_name_trait;
       ^
3 errors generated.

最佳答案

Boost.Compute基于OpenCL,可能不是您想要的。
而是使用Boost.Iterator库:

#include <boost/iterator/transform_iterator.hpp>

boost::make_transform_iterator(_items.begin(), &get_value);

关于c++ - 在std::unique_ptr的 vector 上使用make_transform_iterator获取const指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64064399/

相关文章:

c++ - C++17 之前的函数交错

c++ - 线程是否需要获得互斥量的所有权才能关闭互斥量的句柄

c++ - boost::any,变体,基于它们的数组调用函数

c++ - Boost GIL 图像构造函数

c++ - boost asio 打开更多的一个套接字

c++ - 在文件上实现迭代器

c++ - synchronized_pool_resource 实际是如何工作的?

android - 使用 C++ 为 Android 和 iOS 制作 OpenGLES 2.0 库

c++ - *&var 是多余的吗?

c++ - 静态函数链接器错误