std::bind 在 std::array 的 operator[] 上
std::bind on operator[] of std::array
我试图在 std::array 或 operator[] 处绑定一个成员函数,但编译器 (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;
}
编译错误为:
no matching function for call to 'bind(, const std::_Placeholder<1>&, const
std::_Placeholder<2>&)'
auto arr_x = std::bind(&array::at, _1, _2);
^
我已经意识到导致此错误的原因,但我仍然不知道如何解决。问题是编译器不知道我指的是哪个函数,因为这些函数有 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版本和non-const版本如何绑定?
因为你有两个重载:
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
您还可以使用 lambda 以更优雅的方式解决您的问题:
auto x2 = [&ma](auto const p) { return ma.at(p); };
std::cout << x2(0) << std::endl; // output: 1
我试图在 std::array 或 operator[] 处绑定一个成员函数,但编译器 (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;
}
编译错误为:
no matching function for call to 'bind(, const std::_Placeholder<1>&, const std::_Placeholder<2>&)' auto arr_x = std::bind(&array::at, _1, _2); ^
我已经意识到导致此错误的原因,但我仍然不知道如何解决。问题是编译器不知道我指的是哪个函数,因为这些函数有 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版本和non-const版本如何绑定?
因为你有两个重载:
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
您还可以使用 lambda 以更优雅的方式解决您的问题:
auto x2 = [&ma](auto const p) { return ma.at(p); };
std::cout << x2(0) << std::endl; // output: 1