• Lamda as Operator Overload

    From =?ISO-8859-1?Q?=D6=F6_Tiib?=@21:1/5 to Adi Shavit on Wed Apr 27 08:44:07 2016
    On Wednesday, 27 April 2016 14:50:10 UTC+3, Adi Shavit wrote:
    Is it possible to create a lambda that behaves like an operator
    overload?

    No, not even as 'operator()' overload for something else since those
    are totally different things. Lambda is an object of anonymous class
    that has its own 'operator()' overload. That is it.

    That is, instead of calling it with the operator() syntax, it will be
    called by some other, e.g. binary, infix operator.

    It is indeed possible to make an operator overload that calls whatever
    callable object (including lambda) stored in variable somewhere for
    actually doing its work.


    Is it possible to generically simulate this somehow just like lambdas
    can as structs overloading the () operator. The problem is just how to
    get the compiler/ADL to call the correct function based on the operator.

    I am sort of unsure what you want to accomplish. Perhaps you need
    to start with motivating example problem. Do you want generic
    lambdas of C++14? Those are simple. It is like that:

    auto glambda = [] (auto a) { return a; };

    We made a 'glambda' variable that contains an object of this type:

    class /* unnamed */
    {
    public:
    template<typename T>
    T operator () (T a) const { return a; }
    };

    Now if you want you can call that 'glambda' from some template operator.


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Adi Shavit@21:1/5 to All on Wed Apr 27 15:14:55 2016
    I don't see how. The point about a lambda is that it creates a thing
    without a name (that you can then store in a named variable, but the thing itself is nameless), whereas operator overloading works precisely on the basis of the name of the (member)function.


    Well, most lambdas are eventually stored in a named variable so that they
    can be called at a later time. When called they are evoked like functions
    via the function call operator.
    My question was whether it is possible to create a lambda-like object that
    can be evoked using an operator that is not the function call operator, or, e.g. with an infix operator.


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Adi Shavit@21:1/5 to All on Wed Apr 27 06:46:47 2016
    { edited by mod to shorten lines to ~70 characters. -mod }

    Hi,

    Is it possible to create a lambda that behaves like an operator
    overload?
    That is, instead of calling it with the operator() syntax, it will be
    called by some other, e.g. binary, infix operator.

    Is it possible to generically simulate this somehow just like lambdas
    can as structs overloading the () operator. The problem is just how to
    get the compiler/ADL to call the correct function based on the operator.

    Thanks!
    Adi


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Adi Shavit@21:1/5 to All on Wed Apr 27 17:13:10 2016
    It is indeed possible to make an operator overload that calls
    whatever callable object (including lambda) stored in variable
    somewhere for actually doing its work.

    I don't know why one would want this kind of thing but

    #include <iostream>

    template<typename Callable>
    struct bracketized: private Callable
    {
    bracketized(const Callable &c): Callable(c) {}

    template<typename Param>
    auto operator[](Param&& p)
    -> decltype((*this)(std::forward<Param>(p)))
    {
    return (*this)(std::forward<Param>(p));
    }
    };

    template<typename Callable>
    bracketized<Callable> bracketize(const Callable &c)
    {
    return c;
    }

    int main()
    {
    int i = 1;
    auto lambda = [&](int j) { i += j; };
    auto b = bracketize(lambda);

    b[42];
    std::cout << i;
    }

    builds and runs OK with g++-4.7 -std=c++11.
    With -O it even computes 43 at compile time.

    That's quite clever, though I am not sure this gives me
    what I meant. In this case the bracket operator is essentially like the function
    call operator.

    I am more interested in overloading the arithmetic and logic
    infix operators (+,+=, &, &=, etc) where one does not invoke the function explicitly.

    Do you think this approach will work for that type of operator?
    Could you "plusize" an add() lambda?



    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Martin Bonner@21:1/5 to Adi Shavit on Wed Apr 27 08:44:23 2016
    On Wednesday, 27 April 2016 13:50:10 UTC+2, Adi Shavit wrote:
    Is it possible to create a lambda that behaves like an operator
    overload?
    That is, instead of calling it with the operator() syntax, it will be
    called by some other, e.g. binary, infix operator.

    Is it possible to generically simulate this somehow just like lambdas
    can as structs overloading the () operator. The problem is just how to
    get the compiler/ADL to call the correct function based on the operator.

    I don't see how. The point about a lambda is that it creates a thing
    without a name (that you can then store in a named variable, but the thing itself is nameless), whereas operator overloading works precisely on the
    basis of the name of the (member)function.


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kalle Olavi Niemitalo@21:1/5 to ootiib@hot.ee on Wed Apr 27 15:21:08 2016
    Öö Tiib <ootiib@hot.ee> writes:

    It is indeed possible to make an operator overload that calls
    whatever callable object (including lambda) stored in variable
    somewhere for actually doing its work.

    I don't know why one would want this kind of thing but

    #include <iostream>

    template<typename Callable>
    struct bracketized: private Callable
    {
    bracketized(const Callable &c): Callable(c) {}

    template<typename Param>
    auto operator[](Param&& p)
    -> decltype((*this)(std::forward<Param>(p)))
    {
    return (*this)(std::forward<Param>(p));
    }
    };

    template<typename Callable>
    bracketized<Callable> bracketize(const Callable &c)
    {
    return c;
    }

    int main()
    {
    int i = 1;
    auto lambda = [&](int j) { i += j; };
    auto b = bracketize(lambda);

    b[42];
    std::cout << i;
    }

    builds and runs OK with g++-4.7 -std=c++11.
    With -O it even computes 43 at compile time.


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?ISO-8859-1?Q?=D6=F6_Tiib?=@21:1/5 to Adi Shavit on Thu Apr 28 06:30:29 2016
    On Thursday, 28 April 2016 01:20:08 UTC+3, Adi Shavit wrote:
    It is indeed possible to make an operator overload that calls
    whatever callable object (including lambda) stored in variable
    somewhere for actually doing its work.

    I don't know why one would want this kind of thing but

    #include <iostream>

    template<typename Callable>
    struct bracketized: private Callable
    {
    bracketized(const Callable &c): Callable(c) {}

    template<typename Param>
    auto operator[](Param&& p)
    -> decltype((*this)(std::forward<Param>(p)))
    {
    return (*this)(std::forward<Param>(p));
    }
    };

    template<typename Callable>
    bracketized<Callable> bracketize(const Callable &c)
    {
    return c;
    }

    int main()
    {
    int i = 1;
    auto lambda = [&](int j) { i += j; };
    auto b = bracketize(lambda);

    b[42];
    std::cout << i;
    }

    builds and runs OK with g++-4.7 -std=c++11.
    With -O it even computes 43 at compile time.

    That's quite clever, though I am not sure this gives me
    what I meant. In this case the bracket operator is essentially like the function
    call operator.

    You perhaps need to type it here explicitly what code you have and what
    you want it to look like.


    I am more interested in overloading the arithmetic and logic
    infix operators (+,+=, &, &=, etc) where one does not invoke the function explicitly.

    Do you think this approach will work for that type of operator?
    Could you "plusize" an add() lambda?

    C++ syntax can be altered rather heavily with macros and templates
    and operator overloading. However beware. Making different language
    using C++ is generally bad idea. Tiny typo in usage will typically
    cause hard to understand diagnostics about such bastardization code
    and all the immersion is gone.


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)