Home > Net >  passing std::plus as an argument
passing std::plus as an argument

Time:02-07

How do I pass std::plus as an argument across functions?

#include<functional>
#include<iostream>

template < class T, typename F >
T fn(T a, T b, F f)
{
        return f<T>()(a,b);
}

template<class T>
struct X
{
    template < typename F>
    T foo(T a, T b, F f)
    {
        return fn<T, F>(a,b,f);
    }
};

int main()
{
    int a = 1;
    int b = 1;
    X<int> f;
    std::cout<< f.foo(a,b, std::plus<int>);
    return 0;
}

https://onlinegdb.com/g5NZc2x9V

main.cpp:7:21: error: expected primary-expression before ‘)’ token

CodePudding user response:

std::cout<< f.foo(a,b, std::plus<int>);

std::plus<int> is a type. Just like int. This fails for the exact same reason the following code would fail to compile, too:

void function(int n)
{
}

void another_function()
{
    function(int);
}

You can't "pass std::plus as an argument" for the same exact reason you can't pass int as an argument.

What you can do, though -- and what you should do --- is to construct an instance of std::plus:

std::cout<< f.foo(a,b, std::plus<int>{});

Now, this passes an actual object, std::plus<int> to this function. However this is not going to be sufficient:

T fn(T a, T b, F f)
{
        return f<T>()(a,b);
}

Here, f is going to be that std::plus<int> object. It is a callable object, so, well, all you have to do is call it:

T fn(T a, T b, F f)
{
        return f(a,b);
}

CodePudding user response:

If you want to pass std::plus as a runtime argument you have to actually construct one. You can't pass a type as an argument and trying to pass a naked std::plus<int> is akin to writing a class or typename there i.e. you would not expect foo(a,b, int) to compile if it expects the third argument to be an int value.

#include <functional>
#include <iostream>

template < class T, typename F >
T fn(T a, T b, F f)
{
    return f(a, b);
}

template<class T>
struct X
{
    template < typename F>
    T foo(T a, T b, F f)
    {
        return fn<T, F>(a, b, f);
    }
};

int main()
{
    int a = 1;
    int b = 1;
    X<int> f;
    std::cout << f.foo(a, b, std::plus<int>());
    return 0;
}

CodePudding user response:

std::plus<int> is a type, not an object or function. So you cannot pass it to a function. You can however create an object of that type and pass that:

std::cout<< f.foo(a,b, std::plus<int>{});

Then in the call

return f<T>()(a,b);

the template arguments and first () make no sense. f is not a template, it is an object whose operator() you want to call, so:

return f(a,b);
  •  Tags:  
  • Related