Home > Software engineering >  Any way to create an anonymous reference container in C ?
Any way to create an anonymous reference container in C ?

Time:05-27

In python, we can simply using such code:

a = [1,2,3]
b = [4,5,6]
for m in [a, b]:
    for e in m:
        print(e)

"[a, b]" is an "anonymous" container which contains the "reference" of a and b, during the traverse, none of additional list is created so that the traverse is very effective.

Is there any way to do the same thing in C ? I've tried using vector to do it, but vector always copies objects instead of inferencing, and I haven't found such an "anonymous" way to do it.

CodePudding user response:

Not sure what C you're on.

C 17 onwards it can be done like this:

#include <vector>
#include <functional>
#include <iostream>

int main(int, char*[])
{
    std::vector a{1,2,3};
    std::vector b{3,4,5};
    
    for ( auto&& v : std::vector{std::ref(a), std::ref(b)}) {
        for (int& el : v.get()) {
            std::cout <<el<<'\n';
        }
    }
}

https://godbolt.org/z/8rvh6snz1

C 11 and C 14 version is actually the same, except for the lack of template deduction, so it all gets longer:

    std::vector<int> a{1,2,3};
    std::vector<int> b{3,4,5};
    
    std::vector<std::reference_wrapper<std::vector<int>>> m{std::ref(a), std::ref(b)};

A for C 98... there is no ranged for loop, reference wrapper is provided by Boost:

#include <vector>
#include <iostream>
#include <boost/core/ref.hpp>

int main(int, char*[])
{
    std::vector<int> a;
    a.push_back(1);
    a.push_back(2);
    a.push_back(3);
    std::vector<int> b;
    b.push_back(4);
    b.push_back(5);
    b.push_back(6);
    std::vector<boost::reference_wrapper<std::vector<int> > > m;
    m.push_back(boost::ref(a));
    m.push_back(boost::ref(b));

    for(std::vector<boost::reference_wrapper<std::vector<int> > >::iterator it=m.begin(), e=m.end();
        it!=e;   it) {
        for(std::vector<int>::iterator ii=(*it).get().begin(), ie=(*it).get().end();
        ii!=ie;   ii) {
            std::cout << *ii << '\n';
        } 
    }
}

https://godbolt.org/z/3n8jobz4h

Lots of other convenience functions are also provided by Boost, so feel free to have a closer look at it. I just wanted to limit its usage to the bare minimum.

  • Related