Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is There a Indirection Functor?

I'm looking for a unary functor which will dereference it's argument and return the result. Of course I can write one, it just seemed like something should already exist.

So given the code:

const auto vals = { 0, 1, 2, 3 };
vector<const int*> test(size(vals), nullptr);

iota(begin(test), end(test), data(vals));

transform(cbegin(test), cend(test), ostream_iterator<int>(cout, " "), [](const auto& i){ return *i; });

Live Example

I was hoping that there was a functor that I could use instead of the lambda. Does such a thing exist, or do I need to just use the lambda?

like image 639
Jonathan Mee Avatar asked Jan 05 '17 14:01

Jonathan Mee


People also ask

Is a functor a function?

A functor (or function object) is a C++ class that acts like a function. Functors are called using the same old function call syntax.

What is a functor in C++?

A C++ functor (function object) is a class or struct object that can be called like a function. It overloads the function-call operator () and allows us to use an object like a function.

Why do we need functors?

Functors give you more flexibility, at the cost of usually using slightly more memory, at the cost of being more difficult to use correctly, and at the cost of some efficiency.

What is an STL function object?

A function object (or functor) is simply any object of a class that provides at least one definition for operator() What this means is that if you then declare an object f of the class in which this operator() is defined you can subsequently use that object f just like you would use an "ordinary" function.


1 Answers

Assuming that by "functor" you mean "function object" or "callable object", there doesn't seem to be what you desire in the Standard Library.

It is trivial to implement it yourself:

struct deferencer
{
    template <typename T>
    decltype(auto) operator()(T&& x) const
        noexcept(noexcept(*x))
    { 
        return *x; 
    }
};

Note that your lambda doesn't do what you expect, as its implicit return type is -> auto, which makes a copy. One possible correct lambda is:

[](const auto& i) -> decltype(auto) { return *i; }

If you don't specify an explicit trailing return type for a lambda, the implicit one will be auto which is always a copy. It doesn't matter if operator* returns a reference, since the lambda returns a copy (i.e. the reference returned by operator* is then copied by the lambda's return statement).

struct A
{
    A() = default;
    A(const A&) { puts("copy ctor\n"); }
};

int main()
{
    []{ return *(new A); }(); // prints "copy ctor"
}

wandbox example

like image 87
Vittorio Romeo Avatar answered Sep 21 '22 09:09

Vittorio Romeo