c++ - How should I convert a container to a container of reference_wrappers? -


question:

assume function

void dofoo(const std::vector<std::reference_wrapper<datat> >& data); 

where datat type holding data. used std::vector typical example of container class.

what elegant way call above function std::vector<datat>?

background:

inside function dofoo(...) don't want take ownership of data. thus, don't want use std::shared_ptr or std::unique_ptr. understand correct way use reference. if use reference std::vector<datat> might have copy several datat create vector function call in case did not construct data directly in std::vector<datat>. thus, std::vector<std::reference_wrapper<datat> > seems best solution.

if have single datat object (let's call data1) can put function calling dofoo({data1}) , correct vector constructed implicitly. if have std::vector<datat> datavec , try call dofoo(datavec)it not implicitly converted std::vector<std::reference_wrapper<datat> >, because types unrelated.

possible solutions:

  1. create std::vector<std::reference_wrapper<datat> > before calling function , fill references elements in datavec.
    disadvantage: have repacking each function call.
  2. overload dofoo(...) take std::vector<datat> , repacking there.
    disadvantage: if use concept in many places creates quite boilerplate code. also, me seems bit redundant , maybe confusing have function call.
  3. enable implicit conversion std::vector<datat> std::vector<std::reference_wrapper<datat> >. don't know whether possible @ all, , if might have bad consequences. if or similar possible , safe prefer solution.

i see options here.

1. use iterator constructor of vector.

std::vector<datat> x; dofoo({x.begin(), x.end()}); 

which should construct vector of reference wrappers vector since iterators reference objects anyway.

2. use std::vector<datat> const & dofoo argument , move data vector.

if have data somewhere around can move them vector instead of copying (if moving datat makes sense).

datat d1, d2, d3; std::vector<datat> v { std::move(d1), std::move(d2), std::move(d3) }; doofoo(v); 

which transfers ownership vector (but not function)!

3. operate on datats in vector if there's more 1 handled.

if don't have multiple datat objects around require being copied vector there no need reference_wrapper.


Comments