在 std::unique_ptr 的向量上使用 make_transform_iterator 来获取 const 指针
use make_transform_iterator on vector of std::unique_ptr to get const pointer
我想创建一个 class,它包含一个 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::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);
我想创建一个 class,它包含一个 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::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);