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):

enter image description here

quick demo:

live on coliru

#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:

live on coliru

#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

live on coliru

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

Popular posts from this blog

java - Custom OutputStreamAppender not run: LOGBACK: No context given for <MYAPPENDER> -

java - UML - How would you draw a try catch in a sequence diagram? -

c++ - No viable overloaded operator for references a map -