Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

boost::apply needs to change from lvalue reference to forward reference #26

Closed
jhcarl0814 opened this issue Mar 5, 2021 · 1 comment

Comments

@jhcarl0814
Copy link

boost::apply does not compile when injecting rvalue at function/arguments positions using nested boost::bind:

#include<iostream>
#include<functional>
#include<boost/bind/bind.hpp>
#include<boost/bind/apply.hpp>

class f_t
{
public:
    void operator()(int&)&
    {
        std::cout << 1 << std::endl;
    }
    void operator()(int&&)&
    {
        std::cout << 2 << std::endl;
    }
    void operator()(int&)&&
    {
        std::cout << 3 << std::endl;
    }
    void operator()(int&&)&&
    {
        std::cout << 4 << std::endl;
    }
}f;

int& get_lvalue_arg()
{
    static int a;
    return a;
}

int get_prvalue_arg()
{
    return 1;
}

auto& get_lvalue_f()
{
    return f;
}

auto get_prvalue_f() // function returning [(prvalue) function object]; the same goes for function returning [(prvalue) function pointer]
{
    return f;
}

int main()
{
    boost::bind(boost::apply<void>(), boost::bind(get_lvalue_f), boost::bind(get_lvalue_arg))();
    boost::bind(boost::apply<void>(), boost::bind(get_lvalue_f), boost::bind(get_prvalue_arg))(); //compile error
    boost::bind(boost::apply<void>(), boost::bind(get_prvalue_f), boost::bind(get_lvalue_arg))(); //compile error
    boost::bind(boost::apply<void>(), boost::bind(get_prvalue_f), boost::bind(get_prvalue_arg))(); //compile error

    boost::bind(boost::apply<void>(), boost::bind(boost::apply<f_t&>(), boost::placeholders::_1), boost::bind(boost::apply<int&>(), boost::placeholders::_2))(get_lvalue_f, get_lvalue_arg);
    boost::bind(boost::apply<void>(), boost::bind(boost::apply<f_t&>(), boost::placeholders::_1), boost::bind(boost::apply<int>(), boost::placeholders::_2))(get_lvalue_f, get_prvalue_arg); //compile error
    boost::bind(boost::apply<void>(), boost::bind(boost::apply<f_t>(), boost::placeholders::_1), boost::bind(boost::apply<int&>(), boost::placeholders::_2))(get_prvalue_f, get_lvalue_arg); //compile error
    boost::bind(boost::apply<void>(), boost::bind(boost::apply<f_t>(), boost::placeholders::_1), boost::bind(boost::apply<int>(), boost::placeholders::_2))(get_prvalue_f, get_prvalue_arg); //compile error

    std::bind(f, std::bind(get_lvalue_arg))();
    std::bind(f, std::bind(get_prvalue_arg))();
}

expected output:

1
2
3
4
1
2
3
4
1
2

workaround:
in <boost/bind/apply.hpp>, change:

template<class F, class A1> result_type operator()(F & f, A1 & a1) const
{
    return f(a1);
}

to:

template<class F, class A1> result_type operator()(F&& f, A1&& a1) const
{
    return ((F&&)f)((A1&&)a1);
}
@pdimov
Copy link
Member

pdimov commented Mar 6, 2021

Should be fixed on develop. Thank you for the report.

@pdimov pdimov closed this as completed Mar 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants