簡體   English   中英

成員變量和STL算法

[英]Member variables and STL algorithms

#include <vector>
#include <functional>
#include <algorithm>
using namespace std;

struct Foo
{
    int i;
    double d;
    Foo(int i, double d) :
        i(i),
        d(d)
    {}
    int getI() const { return i; }
};

int main()
{
    vector<Foo> v;
    v.push_back(Foo(1, 2.0));
    v.push_back(Foo(5, 3.0));

    vector<int> is;

    transform(v.begin(), v.end(), back_inserter(is), mem_fun_ref(&Foo::getI));

    return 0;
}

是否有更簡潔的方法來訪問成員變量然后使用像我上面的成員函數? 我知道如何使用tr1 :: bind來完成它,但是我需要沒有boost的C ++ 03兼容代碼。

為了做到這一點,需要一個訪問器功能是絕對不潔凈的。 但那是當前的C ++。

你可以嘗試使用boost::bind ,它很容易做到這一點,或者使用for( vector<int>::const_iterator it = v.begin(); .....)循環顯式迭代向量。 當發現仿函數的創建變得太麻煩時,我發現后者通常會產生更清晰的代碼。

或者,避開提升,創建自己的member-accessor shim函數。

template< typename T, typename m > struct accessor_t {
   typedef m (T::*memberptr);

   memberptr acc_;

   accessor_t( memberptr acc ): acc_(acc){}
   // accessor_t( m (T::*acc) ): acc_(acc){}
   // m (T::*acc_);

   const m& operator()( const T& t ) const { return (t.*acc_); }
   m&       operator()( T& t       ) const { return (t.*acc_); }
};

template< typename T, typename m > accessor_t<T,m> accessor( m T::*acc ) {
   return accessor_t<T,m>(acc);
}

...

transform( v.begin(), v.end(), back_inserter(is), accessor( &C::i ) );

像std :: pair一樣,你可以編寫訪問或對象。

#include <vector>
#include <algorithm>

struct Foo
{
    int i;
    double d;
};

struct GetI { int    operator()(Foo const& o) const { return o.i;}};
struct GetD { double operator()(Foo const& o) const { return o.d;}};

int main()
{
    std::vector<Foo>    v;
    std::vector<int>    t;
    std::transform(v.begin(), v.end(), std::back_inserter(t),GetI() );
}

注意:您應該查看std :: pair <T1,T2>
及其訪問器:std :: select1st <T1>和std :: select2nd <T2>

對我來說最明確的方法是boost::bind

#include <boost/bind.hpp>

...

transform(v.begin(), v.end(), back_inserter(is), bind( &Foo::i, _1 ) );

當然,您可以創建自己的成員訪問功能,但我相信它會降低您的代碼的可讀性。 boost :: bind是眾所周知的庫,因此使用它將使您的代碼具有可讀性並且無需讀取輔助函數(偶爾可能包含錯誤)

我更喜歡的第二種方式是使用for循環(在這種特殊情況下):

for ( vector<Foo>::const_iterator it = v.begin(), it != v.end(); ++it )
    is.push_back( it->i );

使用這種簡單的循環可能不是時髦,但它們非常清晰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM