samedi 25 janvier 2020

std::bind on operator[] of std::array

I am trying to bind a member function at or operator[] of std::array, but the compiler (gcc 7.3) says that it can't determine the typename _Func. So I had created my own struct array to see where the problem is. But it works fin in this case.


    #include <iostream>
    #include <functional>
    #include <array>

    template<typename ret, unsigned int size>
    struct my_arr {
        ret data[size];

        ret& at(unsigned int i) {return data[i];}

        ret& operator[](unsigned int i){return data[i];}
    };

    using namespace std::placeholders;
    using namespace std;

    int main() {

        my_arr<int,3> ma = {1,2,3};

        auto x = std::bind(&my_arr<int,3>::at, _1, 0); // ok

        auto x1 = std::bind(&my_arr<int,3>::operator[], _1, 0); // ok

        auto arr_x = std::bind(&array<double, 3>::at, _1, _2); // error

        auto arr_x = std::bind(&array<double, 3>::operator[], _1, _2); // error

        std::cout << x(ma) << std::endl << x1(ma) << std::endl;

    }

The compile error is:

no matching function for call to 'bind(<unresolved overloaded function type>, const std::_Placeholder<1>&, const std::_Placeholder<2>&)'
 auto arr_x = std::bind(&array<double, 3>::at, _1, _2);
                                                     ^

I have realized what causes this error, but I still don't know how to solve it. The problem is that the compiler doesn't know which function do I reffer to, because there are const and non-const variants of these functions. This code simulates the same error.

    #include <iostream>
    #include <functional>
    #include <array>

    template<typename ret, unsigned int size>
    struct my_arr {
        ret data[size];

        ret& at(unsigned int i) {return data[i];}
        const ret& at(unsigned int i) const {return data[i];}
        ret& operator[](unsigned int i){return data[i];}
    };

    using namespace std::placeholders;
    using namespace std;

    int main() {

        my_arr<int,3> ma = {1,2,3};

        auto x = std::bind(&my_arr<int,3>::at, _1, 0); // error

        auto x1 = std::bind(&my_arr<int,3>::operator[], _1, 0); // ok

        std::cout << x(ma) << std::endl << x1(ma) << std::endl;

    }

I still don't know how to specify which version of function I want to call, how to bind the const version and the non-const one?

Aucun commentaire:

Enregistrer un commentaire