Search code examples
c++boostbindblitz++

how to bind vector.resize


I try to use boost::bind with std::vector<>::resize.

But the following code won't compile:

#include <boost/bind.hpp>
#include <vector>
using namespace boost;

int main(){
    typedef std::vector<double> type;
    type a;
    bind(&type::resize, _1, 2)(a);
    return 0;
}

So, how can I do this?

Thanks!

boost version 1.53 gcc version 4.8 or 4.6

*Edit: * The above code works with -std=c++11. In fact, my original problem is this:

#include <boost/bind.hpp>
#include <blitz/array.h>
#include <vector>
using namespace boost;
using namespace blitz;

int main(){
    typedef Array<double, 1> type;
    type a;
            //a.resize(4) is ok;
    bind(&type::resize, _1, 2)(a);
    return 0;
}

My compile command is: g++ t.cpp -I path/include/ -std=c++11 -L path/lib/ -l blitz


Solution

  • resize might be an overloaded function (in C++11 it has to be) so you need to tell the compiler which overload you want. For the one argument form, this should work in C++11:

    bind(static_cast<void (type::*)(type::size_type)>(&type::resize), _1, 2)(a);
    

    Or more readably:

    typedef void (type::*resize_signature)(type::size_type);
    bind(static_cast<resize_signature>(&type::resize), _1, 2)(a);
    

    If it's not an overloaded function (as with GCC in C++03 mode) then it takes two arguments (one has a default value) and you need to supply the second argument because bind can't use default arguments:

    typedef void (type::*resize_signature)(type::size_type, const value_type&);
    bind(static_cast<resize_signature>(&type::resize), _1, 2, 0.0)(a);
    

    Unfortunately this C++03 version isn't portable, implementations are allowed to use a single function or a pair of overloads. To make it portable, or to work with other types such as Array you can wrap the call in a custom functor that calls resize, so you don't need to know the exact signature:

    typename<class VecT>
    struct resizer<VecT> {
        void operator()(VecT& v, unsigned n) const { v.resize(n); }
    };
    // ...
    bind(resizer<type>(), _1, 2)(a);
    

    Or in C++11 just use a lambda expression instead of bind:

    auto resize = [](type& v) { v.resize(2); };
    resize(a);