c++11 - boost::shared_ptr<std::vector<something>> usage of operator[] -
i have struct looks this.
typedef struct supercellboxstruct { float_tt cmx,cmy,cmz; /* fractional center of mass coordinates */ float_tt ax,by,cz; boost::shared_ptr<std::vector<atom>> atoms; /* contains atoms within super cell */ } supercellbox;
now when want access atoms[i]
error: invalid use of ‘boost::detail::sp_array_access >::type {aka void}’
what proper way of passing around shared vector in application, or correct way access operator[]?
prefer unique_ptr<t[]>
if can, because operator[]
free (§ 20.7.1.3.3):
quick demo:
#include <memory> #include <iostream> int main() { std::unique_ptr<int[]> p(new int[3] { 1,2,3 }); std::cout << "before: " << p[0] << ", " << p[1] << ", " << p[2] << ";\n"; p[1] = 42; std::cout << "after: " << p[0] << ", " << p[1] << ", " << p[2] << ";\n"; }
prints:
before: 1, 2, 3; after: 1, 42, 3;
update
in response comment, make small wrapper:
#include <memory> template <typename racontainer> struct shared_randomaccess_container { template <typename... a> shared_randomaccess_container(a&&... args) : _ptr(new racontainer{ std::forward<a>(args)... }) { } template <typename t> shared_randomaccess_container(std::initializer_list<t> init) : _ptr(std::make_shared<racontainer>(init)) { } auto begin() const -> typename racontainer::const_iterator { return _ptr->begin(); } auto end () const -> typename racontainer::const_iterator { return _ptr->end (); } auto begin() -> typename racontainer::iterator { return _ptr->begin(); } auto end () -> typename racontainer::iterator { return _ptr->end (); } template <typename idx> typename racontainer::value_type const& operator[](idx i) const { return (*_ptr)[i]; } template <typename idx> typename racontainer::value_type& operator[](idx i) { return (*_ptr)[i]; } template <typename idx> typename racontainer::value_type const& at(idx i) const { return _ptr->at(i); } template <typename idx> typename racontainer::value_type& at(idx i) { return _ptr->at(i); } protected: using ptr = std::shared_ptr<racontainer>; ptr _ptr; }; //////////////////////////////////////////////////// // demo intances #include <vector> template <typename... ts> using shared_vector = shared_randomaccess_container<std::vector<ts...> >;
you can use like:
shared_vector<int> sv {1,2,3}; std::cout << "before: "; (auto : sv) std::cout << << " "; sv[1] = 42; std::cout << "\nafter: "; (auto : sv) std::cout << << " ";
prints:
before: 1 2 3 after: 1 42 3
bonus
let's support aggregate initializing containers same technique
output:
void test() [with = std::vector<int>] before: 1 2 3 after: 1 42 3 void test() [with = std::array<int, 3ul>] before: 1 2 3 after: 1 42 3 void test() [with = shared_randomaccess_container<std::vector<int>, false>] before: 1 2 3 after: 1 42 3 void test() [with = shared_randomaccess_container<std::array<int, 3ul>, true>] before: 1 2 3 after: 1 42 3
Comments
Post a Comment