我正在尝试按照第n列的顺序排列一个二维数组vector<vector<int> > a(M,vector<int>(N))
,如下所示:
sort(a.begin(),a.end(),
(bind(&vector<int>::operator[],_1,n) >
bind(&vector<int>::operator[],_2,n)));
然而我的编译器告诉我
error: no matching function for call to ‘bind(<unresolved overloaded function type>, const boost::lambda::placeholder1_type&, int)’
error: no matching function for call to ‘bind(<unresolved overloaded function type>, const boost::lambda::placeholder2_type&, int)’
我该怎么解决这个电话?
PS:尝试了前面对operator []
的访问的更简单版本 vector<int> a(10);
(bind(&vector<int>::operator[],_1,_2))(a,2);
直接来自Karlsson的书,是一个改编的复制剪切和粘贴。获得
error: no matching function for call to ‘bind(<unresolved overloaded function type>, const boost::lambda::placeholder1_type&, const boost::lambda::placeholder2_type&)’
也是为了......
答案 0 :(得分:3)
使用Boost.Phoenix,你可以使用@sellibitze在评论中提到的内容:
#include <iostream>
#include <vector>
#include <boost/phoenix.hpp>
namespace phx=boost::phoenix;
int main()
{
std::vector<std::vector<int>> matrix
{
{1, 2, 3, 4},
{4, 3, 4, 1},
{9, 1, 0, 2},
{3, 1, 5, 1}
};
const auto N = 2;
using phx::arg_names::_1;
using phx::arg_names::_2;
std::sort( matrix.begin(), matrix.end(), _1[N] > _2[N] );
for(const auto& row: matrix)
{
for(const auto& elem: row)
std::cout << elem << ' ';
std::cout << std::endl;
}
return 0;
}
答案 1 :(得分:2)
std::vector
有const
和非const
版本的operator[]
,编译器无法推断,应该使用哪些重载。你可以这样做:
template <class R, class T, class... Args>
auto const_mem_fn(R (T::* pm)(Args...) const)
-> decltype(std::mem_fn(pm))
{
return std::mem_fn(pm);
}
int main()
{
std::vector<std::vector<int>> matrix
{
{1, 2, 3, 4},
{4, 3, 4, 1},
{9, 1, 0, 2},
{3, 1, 5, 1}
};
const auto N = 2;
std::sort
(
matrix.begin(), matrix.end(),
boost::bind(const_mem_fn(&std::vector<int>::operator[]), _1, N) >
boost::bind(const_mem_fn(&std::vector<int>::operator[]), _2, N)
);
for(const auto& row: matrix)
{
for(const auto& elem: row)
std::cout << elem << ' ';
std::cout << std::endl;
}
return 0;
}
或者,没有const_mem_fn
:
const int& (std::vector<int>::*op_sq_br)(std::size_t) const = &std::vector<int>::operator[];
std::sort
(
matrix.begin(), matrix.end(),
boost::bind(op_sq_br, _1, N) >
boost::bind(op_sq_br, _2, N)
);
输出:
3 1 5 1
4 3 4 1
1 2 3 4
9 1 0 2
答案 2 :(得分:2)
正如@soon所说,&std::vector<int>::operator[]
指的是一个重载集。但是你不能将这样的东西传递给一个函数模板,并期望它推断出它的类型,因为它的类型取决于你的意思。所以,在某个地方你必须手动消除歧义。
如果您可以使用C ++ 11功能,那么您应该编写
std::sort(a.begin(),a.end(),
[=](vector<int> const& a, vector<int> const& b) {
return a[n] > b[n];
} );
摆脱超载问题。这里,const的重载只是因为a和b引用了const向量。
如果您希望它与C ++ 98兼容,另一种选择是编写自己的仿函数来应用下标运算符:
template<class ResultType>
struct apply_subscript {
typedef ResultType result_type;
template<class T, class U>
ResultType operator()(T const& x, U const& y) const { return x[y]; }
template<class T, class U>
ResultType operator()(T & x, U const& y) const { return x[y]; }
};
:::
using namespace boost;
sort(mat.begin(),mat.end(),
bind(apply_subscript<int>(),_1,n) >
bind(apply_subscript<int>(),_2,n)
);
HTH
答案 3 :(得分:0)
我想在这里添加一个C ++ 11解决方案,因为你在这里使用Boost并没有真正获得任何东西。
简单的lambda解决方案最有效:std::sort( a.begin(), a.end(), [n]( std::vector< int > first, std::vector< int > second ){ return first[n] < second[n]; } );
使用bind
在很大程度上增加了问题的复杂性:std::sort( a.begin(), a.end(), std::bind( std::less< int >(), std::bind( static_cast< const int&( std::vector< int >::* )( size_t ) const >( &std::vector< int >::operator[] ), std::placeholders::_1, n ), std::bind( static_cast< const int&( std::vector< int >::* )( size_t ) const >( &std::vector< int >::operator[] ), std::placeholders::_1, n ) );
我认为没有任何理由,但是如果你真的依赖于bind
而不是lambdas,你可以通过这样做来最小化static_cast
的肮脏:
auto columnChooser = std::bind( static_cast< const int&( std::vector< int >::* )( size_t ) const >( &std::vector< int >::operator[] ), std::placeholders::_1, n );
std::sort( a.begin(), a.end(), std::bind( std::less< int >(), columnChooser, columnChooser );