如何解决在std :: unique_ptr的向量上使用make_transform_iterator获取常量指针
我想创建一个类,其中包含一个数据结构的unique_ptr向量,并且可以作为指向数据结构的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::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::function<const data *(const
std::__1::unique_ptr<data,std::__1::default_delete<data> > &)> >,const data *,std::__1::random_access_iterator_tag,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,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);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。