Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a standard library function, opposite from addressof?

Tags:

c++

I have an algorithm where am converting to from pointers to a class

std::vector<MyClass>  input;
std::vector<MyClass*> ptrs;
std::vector<MyClass>  output;

So to obtain the ptrs I do

transform(input.begin(), input.end(), back_inserter(ptrs), addressof<MyClass>);

Is there an opposite operation in the standard library, like deref_of so that I could get the result as :

transform(ptrs.begin(), ptrs.end(), back_inserter(output), deref_of<MyClass*>);
like image 892
Nikos Athanasiou Avatar asked Dec 14 '22 22:12

Nikos Athanasiou


2 Answers

You can do this using boost::indirect_iterator.

std::copy(boost::make_indirect_iterator(ptrs.begin()),
          boost::make_indirect_iterator(ptrs.end()),
          std::back_inserter(output));

Live demo

like image 136
Praetorian Avatar answered Dec 17 '22 13:12

Praetorian


No such thing exist in the standard library.

However, you can write it yourself:

template<typename T>
T& deref(T * ptr) { return *ptr; }                //non-const version

template<typename T>
T const & cderef(T const * ptr) { return *ptr; }  //const version   

You've to use it as deref<MyClass>, not deref<MyClass*>.


In C++14, you can use generic lambda to simply it:

auto deref = [](auto * ptr) { return *ptr; };

Now you could use just deref instead of deref<MyClass> (as in the previous case). The type will be inferred by the compiler, anyway. Of course, you could implement this in C++11 (or even in C++03) as:

static const struct deref_t  //static const applies to the object
{
    template<typename T>
    T& operator()(T const * ptr) const { return *ptr; }

}deref;  //declare an object as well.

Use it as deref. It is just like generic lambda.

Hope that helps.

like image 26
Nawaz Avatar answered Dec 17 '22 13:12

Nawaz