std :: std :: array的运算符[]绑定

问题描述 投票:2回答:1

我正在尝试在std :: array的or运算符[]上绑定成员函数,但是编译器(gcc 7.3)表示无法确定类型名_Func。因此,我创建了自己的结构数组以查看问题所在。但是在这种情况下它可以正常工作。

#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;

}

编译错误是:

无匹配函数可调用'bind(,const std :: _ Placeholder <1>&,conststd :: __ Placeholder <2>&)'自动arr_x = std :: bind(&array :: at,_1,_2);^


我已经知道是什么导致了此错误,但我仍然不知道如何解决它。问题在于编译器不知道我要使用哪个函数,因为这些函数有const和non-const变体。此代码模拟相同的错误。
#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;

}

我仍然不知道如何指定我要调用的函数版本,如何绑定const版本和非const版本?

c++ c++11 const bind function-reference
1个回答
3
投票

由于有两个重载:

  • ret& at(unsigned int i)
  • const ret& at(unsigned int i) const

编译器不知道您真正想绑定到哪个函数重载。因此,您需要将函数指针强制转换为确切的函数签名。

这将起作用:

auto x = std::bind(static_cast<int&(my_arr<int, 3>::*)(unsigned int)>(&my_arr<int,3>::at), _1, 0);

签出live

您还可以使用lambdas以更优雅的方式解决问题:

auto x2 = [&ma](auto const p) { return ma.at(p); };
std::cout << x2(0) << std::endl; // output: 1
© www.soinside.com 2019 - 2024. All rights reserved.