Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost bind and 'result_type': is not a member, c++03-friendly

Tags:

The latest 16.6 update to Visual Studio 2019 removed std::plus::result_type, std::minus::result_type, and related typedefs. (They're deprecated in C++17 and removed in C++20.) A greatly simplified version of the code looks like this:

template <typename FF>
struct function_wrapper {
    function_wrapper(FF func, const std::string& name) : func_(func), name_(name) { }
    int operator()(int i1, int i2) const { return func_(i1, i2); }
    // ... other stuff ...
    FF func_;
    std::string name_;
};

template <typename FF>
int use_function(const function_wrapper<FF>& func, const std::pair<int, int>& args) {
    return func(args.first, args.second);
}

funcWrapper<boost::function<int(int, int)>> plus_func(std::plus<int>(), "plus");
std::cout << use_function(plus_func, std::make_pair<int, int>(1, 2)) << std::endl;

After the update, this no longer compiles, generating the error:

boost\1.72.0\boost\bind\bind.hpp(75,25): error C2039: 'result_type': is not a member of 'std::plus<int>'

I can't add a result_type typedef back into std::plus, so I need another way to fix this. The thing is, the resulting code needs to compile under C++03, too, so lambdas and >=C++11 constructs are not a viable option. I can re-implement std::plus and add in the now-removed typedefs myself to make Boost happy, but is there a better way?

like image 596
MaddHatter Avatar asked Jun 05 '20 11:06

MaddHatter


1 Answers

Wrap old functors with:

template <typename F>
struct functor;

template <template <typename> class F, typename T>
struct functor<F<T> > : F<T>
{
    typedef T result_type;
    typedef T first_argument_type;
    typedef T second_argument_type;
};

Then:

function_wrapper<boost::function<int(int, int)> >
     plus_func(functor<std::plus<int> >(), "plus");
//             ~~~~~~~^              ~^~

Alternatively, you can call boost::bind specifying the result type as a template argument:

boost::bind<int>(func, args...);

or:

boost::bind(boost::type<int>(), func, args...);
like image 81
Piotr Skotnicki Avatar answered Oct 12 '22 00:10

Piotr Skotnicki