2

vector<vector<int> > a(M,vector<int>(N))次のように、n 番目の列に関して2 次元配列を行ごとに並べ替えようとしています。

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&)’

そのためにも…

4

4 に答える 4

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;
}
于 2013-04-28T08:59:12.753 に答える
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];
    } );

過負荷の問題を取り除くために。ここでは、単純に a と b が const ベクトルを参照しているため、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

于 2013-04-28T09:11:04.677 に答える
2

std::vectorhasconstと non-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

于 2013-04-28T07:50:26.773 に答える
0

ここで Boost を使用しても実際には何も得られないため、ここに C++11 ソリューションを追加したいと思います。

シンプルなラムダ ソリューションが最適です。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で不快感を最小限に抑えることができます。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 );
于 2014-09-08T11:09:46.307 に答える